mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Revert "Merge branch 'canary' into kucherenko/canary"
This reverts commit819822f30b, reversing changes made tobda9b05134.
This commit is contained in:
@@ -1,56 +1,108 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { db } from "@dokploy/server/db";
|
||||
import {
|
||||
invitation,
|
||||
member,
|
||||
organization,
|
||||
users_temp,
|
||||
admins,
|
||||
type apiCreateUserInvitation,
|
||||
auth,
|
||||
users,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import * as bcrypt from "bcrypt";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { IS_CLOUD } from "../constants";
|
||||
|
||||
export const findUserById = async (userId: string) => {
|
||||
const user = await db.query.users_temp.findFirst({
|
||||
where: eq(users_temp.id, userId),
|
||||
// with: {
|
||||
// account: true,
|
||||
// },
|
||||
export type Admin = typeof admins.$inferSelect;
|
||||
export const createInvitation = async (
|
||||
input: typeof apiCreateUserInvitation._type,
|
||||
adminId: string,
|
||||
) => {
|
||||
await db.transaction(async (tx) => {
|
||||
const result = await tx
|
||||
.insert(auth)
|
||||
.values({
|
||||
email: input.email.toLowerCase(),
|
||||
rol: "user",
|
||||
password: bcrypt.hashSync("01231203012312", 10),
|
||||
})
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
if (!result) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error creating the user",
|
||||
});
|
||||
}
|
||||
const expiresIn24Hours = new Date();
|
||||
expiresIn24Hours.setDate(expiresIn24Hours.getDate() + 1);
|
||||
const token = randomBytes(32).toString("hex");
|
||||
await tx
|
||||
.insert(users)
|
||||
.values({
|
||||
adminId: adminId,
|
||||
authId: result.id,
|
||||
token,
|
||||
expirationDate: expiresIn24Hours.toISOString(),
|
||||
})
|
||||
.returning();
|
||||
});
|
||||
if (!user) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "User not found",
|
||||
});
|
||||
}
|
||||
return user;
|
||||
};
|
||||
|
||||
export const findOrganizationById = async (organizationId: string) => {
|
||||
const organizationResult = await db.query.organization.findFirst({
|
||||
where: eq(organization.id, organizationId),
|
||||
export const findAdminById = async (adminId: string) => {
|
||||
const admin = await db.query.admins.findFirst({
|
||||
where: eq(admins.adminId, adminId),
|
||||
});
|
||||
return organizationResult;
|
||||
if (!admin) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Admin not found",
|
||||
});
|
||||
}
|
||||
return admin;
|
||||
};
|
||||
|
||||
export const updateAdmin = async (
|
||||
authId: string,
|
||||
adminData: Partial<Admin>,
|
||||
) => {
|
||||
const admin = await db
|
||||
.update(admins)
|
||||
.set({
|
||||
...adminData,
|
||||
})
|
||||
.where(eq(admins.authId, authId))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
return admin;
|
||||
};
|
||||
|
||||
export const isAdminPresent = async () => {
|
||||
const admin = await db.query.member.findFirst({
|
||||
where: eq(member.role, "owner"),
|
||||
});
|
||||
|
||||
const admin = await db.query.admins.findFirst();
|
||||
if (!admin) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export const findAdmin = async () => {
|
||||
const admin = await db.query.member.findFirst({
|
||||
where: eq(member.role, "owner"),
|
||||
export const findAdminByAuthId = async (authId: string) => {
|
||||
const admin = await db.query.admins.findFirst({
|
||||
where: eq(admins.authId, authId),
|
||||
with: {
|
||||
user: true,
|
||||
users: true,
|
||||
},
|
||||
});
|
||||
if (!admin) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Admin not found",
|
||||
});
|
||||
}
|
||||
return admin;
|
||||
};
|
||||
|
||||
export const findAdmin = async () => {
|
||||
const admin = await db.query.admins.findFirst({});
|
||||
if (!admin) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
@@ -61,15 +113,14 @@ export const findAdmin = async () => {
|
||||
};
|
||||
|
||||
export const getUserByToken = async (token: string) => {
|
||||
const user = await db.query.invitation.findFirst({
|
||||
where: eq(invitation.id, token),
|
||||
columns: {
|
||||
id: true,
|
||||
email: true,
|
||||
status: true,
|
||||
expiresAt: true,
|
||||
role: true,
|
||||
inviterId: true,
|
||||
const user = await db.query.users.findFirst({
|
||||
where: eq(users.token, token),
|
||||
with: {
|
||||
auth: {
|
||||
columns: {
|
||||
password: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -79,23 +130,34 @@ export const getUserByToken = async (token: string) => {
|
||||
message: "Invitation not found",
|
||||
});
|
||||
}
|
||||
|
||||
const userAlreadyExists = await db.query.users_temp.findFirst({
|
||||
where: eq(users_temp.email, user?.email || ""),
|
||||
});
|
||||
|
||||
const { expiresAt, ...rest } = user;
|
||||
return {
|
||||
...rest,
|
||||
isExpired: user.expiresAt < new Date(),
|
||||
userAlreadyExists: !!userAlreadyExists,
|
||||
...user,
|
||||
isExpired: user.isRegistered,
|
||||
};
|
||||
};
|
||||
|
||||
export const removeUserById = async (userId: string) => {
|
||||
export const removeUserByAuthId = async (authId: string) => {
|
||||
await db
|
||||
.delete(users_temp)
|
||||
.where(eq(users_temp.id, userId))
|
||||
.delete(auth)
|
||||
.where(eq(auth.id, authId))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
};
|
||||
|
||||
export const removeAdminByAuthId = async (authId: string) => {
|
||||
const admin = await findAdminByAuthId(authId);
|
||||
if (!admin) return null;
|
||||
|
||||
// First delete all associated users
|
||||
const users = admin.users;
|
||||
|
||||
for (const user of users) {
|
||||
await removeUserByAuthId(user.authId);
|
||||
}
|
||||
// Then delete the auth record which will cascade delete the admin
|
||||
return await db
|
||||
.delete(auth)
|
||||
.where(eq(auth.id, authId))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
};
|
||||
@@ -106,8 +168,8 @@ export const getDokployUrl = async () => {
|
||||
}
|
||||
const admin = await findAdmin();
|
||||
|
||||
if (admin.user.host) {
|
||||
return `https://${admin.user.host}`;
|
||||
if (admin.host) {
|
||||
return `https://${admin.host}`;
|
||||
}
|
||||
return `http://${admin.user.serverIp}:${process.env.PORT}`;
|
||||
return `http://${admin.serverIp}:${process.env.PORT}`;
|
||||
};
|
||||
|
||||
@@ -4,8 +4,9 @@ import {
|
||||
type apiCreateApplication,
|
||||
applications,
|
||||
buildAppName,
|
||||
cleanAppName,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { getAdvancedStats } from "@dokploy/server/monitoring/utils";
|
||||
import { getAdvancedStats } from "@dokploy/server/monitoring/utilts";
|
||||
import {
|
||||
buildApplication,
|
||||
getBuildCommand,
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
getCustomGitCloneCommand,
|
||||
} from "@dokploy/server/utils/providers/git";
|
||||
import {
|
||||
authGithub,
|
||||
cloneGithubRepository,
|
||||
getGithubCloneCommand,
|
||||
} from "@dokploy/server/utils/providers/github";
|
||||
@@ -173,7 +175,6 @@ export const deployApplication = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
|
||||
const deployment = await createDeployment({
|
||||
applicationId: applicationId,
|
||||
@@ -182,12 +183,6 @@ export const deployApplication = async ({
|
||||
});
|
||||
|
||||
try {
|
||||
// const admin = await findUserById(application.project.userId);
|
||||
|
||||
// if (admin.cleanupCacheApplications) {
|
||||
// await cleanupFullDocker(application?.serverId);
|
||||
// }
|
||||
|
||||
if (application.sourceType === "github") {
|
||||
await cloneGithubRepository({
|
||||
...application,
|
||||
@@ -217,7 +212,7 @@ export const deployApplication = async ({
|
||||
applicationName: application.name,
|
||||
applicationType: "application",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
adminId: application.project.adminId,
|
||||
domains: application.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -230,7 +225,7 @@ export const deployApplication = async ({
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
adminId: application.project.adminId,
|
||||
});
|
||||
|
||||
throw error;
|
||||
@@ -249,7 +244,6 @@ export const rebuildApplication = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const deployment = await createDeployment({
|
||||
applicationId: applicationId,
|
||||
title: titleLog,
|
||||
@@ -257,11 +251,6 @@ export const rebuildApplication = async ({
|
||||
});
|
||||
|
||||
try {
|
||||
// const admin = await findUserById(application.project.userId);
|
||||
|
||||
// if (admin.cleanupCacheApplications) {
|
||||
// await cleanupFullDocker(application?.serverId);
|
||||
// }
|
||||
if (application.sourceType === "github") {
|
||||
await buildApplication(application, deployment.logPath);
|
||||
} else if (application.sourceType === "gitlab") {
|
||||
@@ -296,7 +285,6 @@ export const deployRemoteApplication = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${application.projectId}/services/application/${application.applicationId}?tab=deployments`;
|
||||
const deployment = await createDeployment({
|
||||
applicationId: applicationId,
|
||||
@@ -306,11 +294,6 @@ export const deployRemoteApplication = async ({
|
||||
|
||||
try {
|
||||
if (application.serverId) {
|
||||
// const admin = await findUserById(application.project.userId);
|
||||
|
||||
// if (admin.cleanupCacheApplications) {
|
||||
// await cleanupFullDocker(application?.serverId);
|
||||
// }
|
||||
let command = "set -e;";
|
||||
if (application.sourceType === "github") {
|
||||
command += await getGithubCloneCommand({
|
||||
@@ -349,7 +332,7 @@ export const deployRemoteApplication = async ({
|
||||
applicationName: application.name,
|
||||
applicationType: "application",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
adminId: application.project.adminId,
|
||||
domains: application.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -373,9 +356,17 @@ export const deployRemoteApplication = async ({
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: application.project.organizationId,
|
||||
adminId: application.project.adminId,
|
||||
});
|
||||
|
||||
console.log(
|
||||
"Error on ",
|
||||
application.buildType,
|
||||
"/",
|
||||
application.sourceType,
|
||||
error,
|
||||
);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -394,7 +385,6 @@ export const deployPreviewApplication = async ({
|
||||
previewDeploymentId: string;
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const deployment = await createDeploymentPreview({
|
||||
title: titleLog,
|
||||
description: descriptionLog,
|
||||
@@ -448,15 +438,9 @@ export const deployPreviewApplication = async ({
|
||||
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
|
||||
});
|
||||
application.appName = previewDeployment.appName;
|
||||
application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain}`;
|
||||
application.env = application.previewEnv;
|
||||
application.buildArgs = application.previewBuildArgs;
|
||||
|
||||
// const admin = await findUserById(application.project.userId);
|
||||
|
||||
// if (admin.cleanupCacheOnPreviews) {
|
||||
// await cleanupFullDocker(application?.serverId);
|
||||
// }
|
||||
|
||||
if (application.sourceType === "github") {
|
||||
await cloneGithubRepository({
|
||||
...application,
|
||||
@@ -466,6 +450,7 @@ export const deployPreviewApplication = async ({
|
||||
});
|
||||
await buildApplication(application, deployment.logPath);
|
||||
}
|
||||
// 4eef09efc46009187d668cf1c25f768d0bde4f91
|
||||
const successComment = getIssueComment(
|
||||
application.name,
|
||||
"success",
|
||||
@@ -507,7 +492,6 @@ export const deployRemotePreviewApplication = async ({
|
||||
previewDeploymentId: string;
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const deployment = await createDeploymentPreview({
|
||||
title: titleLog,
|
||||
description: descriptionLog,
|
||||
@@ -561,21 +545,14 @@ export const deployRemotePreviewApplication = async ({
|
||||
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
|
||||
});
|
||||
application.appName = previewDeployment.appName;
|
||||
application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain}`;
|
||||
application.env = application.previewEnv;
|
||||
application.buildArgs = application.previewBuildArgs;
|
||||
|
||||
if (application.serverId) {
|
||||
// const admin = await findUserById(application.project.userId);
|
||||
|
||||
// if (admin.cleanupCacheOnPreviews) {
|
||||
// await cleanupFullDocker(application?.serverId);
|
||||
// }
|
||||
let command = "set -e;";
|
||||
if (application.sourceType === "github") {
|
||||
command += await getGithubCloneCommand({
|
||||
...application,
|
||||
appName: previewDeployment.appName,
|
||||
branch: previewDeployment.branch,
|
||||
serverId: application.serverId,
|
||||
logPath: deployment.logPath,
|
||||
});
|
||||
@@ -625,7 +602,6 @@ export const rebuildRemoteApplication = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const application = await findApplicationById(applicationId);
|
||||
|
||||
const deployment = await createDeployment({
|
||||
applicationId: applicationId,
|
||||
title: titleLog,
|
||||
@@ -634,11 +610,6 @@ export const rebuildRemoteApplication = async ({
|
||||
|
||||
try {
|
||||
if (application.serverId) {
|
||||
// const admin = await findUserById(application.project.userId);
|
||||
|
||||
// if (admin.cleanupCacheApplications) {
|
||||
// await cleanupFullDocker(application?.serverId);
|
||||
// }
|
||||
if (application.sourceType !== "docker") {
|
||||
let command = "set -e;";
|
||||
command += getBuildCommand(application, deployment.logPath);
|
||||
|
||||
184
packages/server/src/services/auth.ts
Normal file
184
packages/server/src/services/auth.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { db } from "@dokploy/server/db";
|
||||
import {
|
||||
admins,
|
||||
type apiCreateAdmin,
|
||||
type apiCreateUser,
|
||||
auth,
|
||||
users,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { getPublicIpWithFallback } from "@dokploy/server/wss/utils";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import * as bcrypt from "bcrypt";
|
||||
import { eq } from "drizzle-orm";
|
||||
import encode from "hi-base32";
|
||||
import { TOTP } from "otpauth";
|
||||
import QRCode from "qrcode";
|
||||
import { IS_CLOUD } from "../constants";
|
||||
|
||||
export type Auth = typeof auth.$inferSelect;
|
||||
|
||||
export const createAdmin = async (input: typeof apiCreateAdmin._type) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const hashedPassword = bcrypt.hashSync(input.password, 10);
|
||||
const newAuth = await tx
|
||||
.insert(auth)
|
||||
.values({
|
||||
email: input.email.toLowerCase(),
|
||||
password: hashedPassword,
|
||||
rol: "admin",
|
||||
})
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
if (!newAuth) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error creating the user",
|
||||
});
|
||||
}
|
||||
|
||||
await tx
|
||||
.insert(admins)
|
||||
.values({
|
||||
authId: newAuth.id,
|
||||
...(!IS_CLOUD && {
|
||||
serverIp:
|
||||
process.env.ADVERTISE_ADDR || (await getPublicIpWithFallback()),
|
||||
}),
|
||||
})
|
||||
.returning();
|
||||
|
||||
return newAuth;
|
||||
});
|
||||
};
|
||||
|
||||
export const createUser = async (input: typeof apiCreateUser._type) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const hashedPassword = bcrypt.hashSync(input.password, 10);
|
||||
const res = await tx
|
||||
.update(auth)
|
||||
.set({
|
||||
password: hashedPassword,
|
||||
})
|
||||
.where(eq(auth.id, input.id))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
if (!res) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Error creating the user",
|
||||
});
|
||||
}
|
||||
|
||||
const user = await tx
|
||||
.update(users)
|
||||
.set({
|
||||
isRegistered: true,
|
||||
expirationDate: undefined,
|
||||
})
|
||||
.where(eq(users.token, input.token))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
return user;
|
||||
});
|
||||
};
|
||||
|
||||
export const findAuthByEmail = async (email: string) => {
|
||||
const result = await db.query.auth.findFirst({
|
||||
where: eq(auth.email, email),
|
||||
});
|
||||
if (!result) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "User not found",
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const findAuthById = async (authId: string) => {
|
||||
const result = await db.query.auth.findFirst({
|
||||
where: eq(auth.id, authId),
|
||||
columns: {
|
||||
password: false,
|
||||
},
|
||||
});
|
||||
if (!result) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Auth not found",
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const updateAuthById = async (
|
||||
authId: string,
|
||||
authData: Partial<Auth>,
|
||||
) => {
|
||||
const result = await db
|
||||
.update(auth)
|
||||
.set({
|
||||
...authData,
|
||||
})
|
||||
.where(eq(auth.id, authId))
|
||||
.returning();
|
||||
|
||||
return result[0];
|
||||
};
|
||||
|
||||
export const generate2FASecret = async (authId: string) => {
|
||||
const auth = await findAuthById(authId);
|
||||
|
||||
const base32_secret = generateBase32Secret();
|
||||
|
||||
const totp = new TOTP({
|
||||
issuer: "Dokploy",
|
||||
label: `${auth?.email}`,
|
||||
algorithm: "SHA1",
|
||||
digits: 6,
|
||||
secret: base32_secret,
|
||||
});
|
||||
|
||||
const otpauth_url = totp.toString();
|
||||
|
||||
const qrUrl = await QRCode.toDataURL(otpauth_url);
|
||||
|
||||
return {
|
||||
qrCodeUrl: qrUrl,
|
||||
secret: base32_secret,
|
||||
};
|
||||
};
|
||||
|
||||
export const verify2FA = async (
|
||||
auth: Omit<Auth, "password">,
|
||||
secret: string,
|
||||
pin: string,
|
||||
) => {
|
||||
const totp = new TOTP({
|
||||
issuer: "Dokploy",
|
||||
label: `${auth?.email}`,
|
||||
algorithm: "SHA1",
|
||||
digits: 6,
|
||||
secret: secret,
|
||||
});
|
||||
|
||||
const delta = totp.validate({ token: pin });
|
||||
|
||||
if (delta === null) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Invalid 2FA code",
|
||||
});
|
||||
}
|
||||
return auth;
|
||||
};
|
||||
|
||||
const generateBase32Secret = () => {
|
||||
const buffer = randomBytes(15);
|
||||
const base32 = encode.encode(buffer).replace(/=/g, "").substring(0, 24);
|
||||
return base32;
|
||||
};
|
||||
@@ -6,7 +6,7 @@ import { eq } from "drizzle-orm";
|
||||
export type Backup = typeof backups.$inferSelect;
|
||||
|
||||
export type BackupSchedule = Awaited<ReturnType<typeof findBackupById>>;
|
||||
export type BackupScheduleList = Awaited<ReturnType<typeof findBackupsByDbId>>;
|
||||
|
||||
export const createBackup = async (input: typeof apiCreateBackup._type) => {
|
||||
const newBackup = await db
|
||||
.insert(backups)
|
||||
@@ -69,20 +69,3 @@ export const removeBackupById = async (backupId: string) => {
|
||||
|
||||
return result[0];
|
||||
};
|
||||
|
||||
export const findBackupsByDbId = async (
|
||||
id: string,
|
||||
type: "postgres" | "mysql" | "mariadb" | "mongo",
|
||||
) => {
|
||||
const result = await db.query.backups.findMany({
|
||||
where: eq(backups[`${type}Id`], id),
|
||||
with: {
|
||||
postgres: true,
|
||||
mysql: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
destination: true,
|
||||
},
|
||||
});
|
||||
return result || [];
|
||||
};
|
||||
|
||||
@@ -12,14 +12,14 @@ export type Bitbucket = typeof bitbucket.$inferSelect;
|
||||
|
||||
export const createBitbucket = async (
|
||||
input: typeof apiCreateBitbucket._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const newGitProvider = await tx
|
||||
.insert(gitProvider)
|
||||
.values({
|
||||
providerType: "bitbucket",
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
name: input.name,
|
||||
})
|
||||
.returning()
|
||||
@@ -74,12 +74,12 @@ export const updateBitbucket = async (
|
||||
.where(eq(bitbucket.bitbucketId, bitbucketId))
|
||||
.returning();
|
||||
|
||||
if (input.name || input.organizationId) {
|
||||
if (input.name || input.adminId) {
|
||||
await tx
|
||||
.update(gitProvider)
|
||||
.set({
|
||||
name: input.name,
|
||||
organizationId: input.organizationId,
|
||||
adminId: input.adminId,
|
||||
})
|
||||
.where(eq(gitProvider.gitProviderId, input.gitProviderId))
|
||||
.returning();
|
||||
|
||||
@@ -33,13 +33,13 @@ export const findCertificateById = async (certificateId: string) => {
|
||||
|
||||
export const createCertificate = async (
|
||||
certificateData: z.infer<typeof apiCreateCertificate>,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
const certificate = await db
|
||||
.insert(certificates)
|
||||
.values({
|
||||
...certificateData,
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { paths } from "@dokploy/server/constants";
|
||||
import { db } from "@dokploy/server/db";
|
||||
import { type apiCreateCompose, compose } from "@dokploy/server/db/schema";
|
||||
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
|
||||
import { generatePassword } from "@dokploy/server/templates/utils";
|
||||
import {
|
||||
buildCompose,
|
||||
getBuildComposeCommand,
|
||||
@@ -205,7 +206,6 @@ export const deployCompose = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${
|
||||
compose.projectId
|
||||
}/services/compose/${compose.composeId}?tab=deployments`;
|
||||
@@ -216,10 +216,6 @@ export const deployCompose = async ({
|
||||
});
|
||||
|
||||
try {
|
||||
// const admin = await findUserById(compose.project.userId);
|
||||
// if (admin.cleanupCacheOnCompose) {
|
||||
// await cleanupFullDocker(compose?.serverId);
|
||||
// }
|
||||
if (compose.sourceType === "github") {
|
||||
await cloneGithubRepository({
|
||||
...compose,
|
||||
@@ -246,7 +242,7 @@ export const deployCompose = async ({
|
||||
applicationName: compose.name,
|
||||
applicationType: "compose",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
adminId: compose.project.adminId,
|
||||
domains: compose.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -261,7 +257,7 @@ export const deployCompose = async ({
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
adminId: compose.project.adminId,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@@ -277,7 +273,6 @@ export const rebuildCompose = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
|
||||
const deployment = await createDeploymentCompose({
|
||||
composeId: composeId,
|
||||
title: titleLog,
|
||||
@@ -285,10 +280,6 @@ export const rebuildCompose = async ({
|
||||
});
|
||||
|
||||
try {
|
||||
// const admin = await findUserById(compose.project.userId);
|
||||
// if (admin.cleanupCacheOnCompose) {
|
||||
// await cleanupFullDocker(compose?.serverId);
|
||||
// }
|
||||
if (compose.serverId) {
|
||||
await getBuildComposeCommand(compose, deployment.logPath);
|
||||
} else {
|
||||
@@ -320,7 +311,6 @@ export const deployRemoteCompose = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
|
||||
const buildLink = `${await getDokployUrl()}/dashboard/project/${
|
||||
compose.projectId
|
||||
}/services/compose/${compose.composeId}?tab=deployments`;
|
||||
@@ -331,10 +321,6 @@ export const deployRemoteCompose = async ({
|
||||
});
|
||||
try {
|
||||
if (compose.serverId) {
|
||||
// const admin = await findUserById(compose.project.userId);
|
||||
// if (admin.cleanupCacheOnCompose) {
|
||||
// await cleanupFullDocker(compose?.serverId);
|
||||
// }
|
||||
let command = "set -e;";
|
||||
|
||||
if (compose.sourceType === "github") {
|
||||
@@ -380,7 +366,7 @@ export const deployRemoteCompose = async ({
|
||||
applicationName: compose.name,
|
||||
applicationType: "compose",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
adminId: compose.project.adminId,
|
||||
domains: compose.domains,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -405,7 +391,7 @@ export const deployRemoteCompose = async ({
|
||||
// @ts-ignore
|
||||
errorMessage: error?.message || "Error building",
|
||||
buildLink,
|
||||
organizationId: compose.project.organizationId,
|
||||
adminId: compose.project.adminId,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@@ -421,7 +407,6 @@ export const rebuildRemoteCompose = async ({
|
||||
descriptionLog: string;
|
||||
}) => {
|
||||
const compose = await findComposeById(composeId);
|
||||
|
||||
const deployment = await createDeploymentCompose({
|
||||
composeId: composeId,
|
||||
title: titleLog,
|
||||
@@ -429,10 +414,6 @@ export const rebuildRemoteCompose = async ({
|
||||
});
|
||||
|
||||
try {
|
||||
// const admin = await findUserById(compose.project.userId);
|
||||
// if (admin.cleanupCacheOnCompose) {
|
||||
// await cleanupFullDocker(compose?.serverId);
|
||||
// }
|
||||
if (compose.serverId) {
|
||||
await getBuildComposeCommand(compose, deployment.logPath);
|
||||
}
|
||||
@@ -557,17 +538,6 @@ export const stopCompose = async (composeId: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (compose.composeType === "stack") {
|
||||
if (compose.serverId) {
|
||||
await execAsyncRemote(
|
||||
compose.serverId,
|
||||
`docker stack rm ${compose.appName}`,
|
||||
);
|
||||
} else {
|
||||
await execAsync(`docker stack rm ${compose.appName}`);
|
||||
}
|
||||
}
|
||||
|
||||
await updateCompose(composeId, {
|
||||
composeStatus: "idle",
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import { removeDirectoryIfExistsContent } from "@dokploy/server/utils/filesystem/directory";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { format } from "date-fns";
|
||||
import { desc, eq } from "drizzle-orm";
|
||||
import { and, desc, eq, isNull } from "drizzle-orm";
|
||||
import {
|
||||
type Application,
|
||||
findApplicationById,
|
||||
@@ -98,17 +98,6 @@ export const createDeployment = async (
|
||||
}
|
||||
return deploymentCreate[0];
|
||||
} catch (error) {
|
||||
await db
|
||||
.insert(deployments)
|
||||
.values({
|
||||
applicationId: deployment.applicationId,
|
||||
title: deployment.title || "Deployment",
|
||||
status: "error",
|
||||
logPath: "",
|
||||
description: deployment.description || "",
|
||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||
})
|
||||
.returning();
|
||||
await updateApplicationStatus(application.applicationId, "error");
|
||||
console.log(error);
|
||||
throw new TRPCError({
|
||||
@@ -175,17 +164,6 @@ export const createDeploymentPreview = async (
|
||||
}
|
||||
return deploymentCreate[0];
|
||||
} catch (error) {
|
||||
await db
|
||||
.insert(deployments)
|
||||
.values({
|
||||
previewDeploymentId: deployment.previewDeploymentId,
|
||||
title: deployment.title || "Deployment",
|
||||
status: "error",
|
||||
logPath: "",
|
||||
description: deployment.description || "",
|
||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||
})
|
||||
.returning();
|
||||
await updatePreviewDeployment(deployment.previewDeploymentId, {
|
||||
previewStatus: "error",
|
||||
});
|
||||
@@ -248,17 +226,6 @@ echo "Initializing deployment" >> ${logFilePath};
|
||||
}
|
||||
return deploymentCreate[0];
|
||||
} catch (error) {
|
||||
await db
|
||||
.insert(deployments)
|
||||
.values({
|
||||
composeId: deployment.composeId,
|
||||
title: deployment.title || "Deployment",
|
||||
status: "error",
|
||||
logPath: "",
|
||||
description: deployment.description || "",
|
||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||
})
|
||||
.returning();
|
||||
await updateCompose(compose.composeId, {
|
||||
composeStatus: "error",
|
||||
});
|
||||
@@ -278,11 +245,9 @@ export const removeDeployment = async (deploymentId: string) => {
|
||||
.returning();
|
||||
return deployment[0];
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Error creating the deployment";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error deleting this deployment",
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -537,11 +502,9 @@ export const createServerDeployment = async (
|
||||
}
|
||||
return deploymentCreate[0];
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Error creating the deployment";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error creating the deployment",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,13 +10,13 @@ export type Destination = typeof destinations.$inferSelect;
|
||||
|
||||
export const createDestintation = async (
|
||||
input: typeof apiCreateDestination._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
const newDestination = await db
|
||||
.insert(destinations)
|
||||
.values({
|
||||
...input,
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -46,14 +46,14 @@ export const findDestinationById = async (destinationId: string) => {
|
||||
|
||||
export const removeDestinationById = async (
|
||||
destinationId: string,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
const result = await db
|
||||
.delete(destinations)
|
||||
.where(
|
||||
and(
|
||||
eq(destinations.destinationId, destinationId),
|
||||
eq(destinations.organizationId, organizationId),
|
||||
eq(destinations.adminId, adminId),
|
||||
),
|
||||
)
|
||||
.returning();
|
||||
@@ -73,7 +73,7 @@ export const updateDestinationById = async (
|
||||
.where(
|
||||
and(
|
||||
eq(destinations.destinationId, destinationId),
|
||||
eq(destinations.organizationId, destinationData.organizationId || ""),
|
||||
eq(destinations.adminId, destinationData.adminId || ""),
|
||||
),
|
||||
)
|
||||
.returning();
|
||||
|
||||
@@ -58,11 +58,7 @@ export const getContainers = async (serverId?: string | null) => {
|
||||
serverId,
|
||||
};
|
||||
})
|
||||
.filter(
|
||||
(container) =>
|
||||
!container.name.includes("dokploy") ||
|
||||
container.name.includes("dokploy-monitoring"),
|
||||
);
|
||||
.filter((container) => !container.name.includes("dokploy"));
|
||||
|
||||
return containers;
|
||||
} catch (error) {
|
||||
@@ -98,7 +94,7 @@ export const getConfig = async (
|
||||
const config = JSON.parse(stdout);
|
||||
|
||||
return config;
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const getContainersByAppNameMatch = async (
|
||||
@@ -156,7 +152,7 @@ export const getContainersByAppNameMatch = async (
|
||||
});
|
||||
|
||||
return containers || [];
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
|
||||
return [];
|
||||
};
|
||||
@@ -214,7 +210,7 @@ export const getStackContainersByAppName = async (
|
||||
});
|
||||
|
||||
return containers || [];
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
|
||||
return [];
|
||||
};
|
||||
@@ -274,7 +270,7 @@ export const getServiceContainersByAppName = async (
|
||||
});
|
||||
|
||||
return containers || [];
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
|
||||
return [];
|
||||
};
|
||||
@@ -325,7 +321,7 @@ export const getContainersByAppLabel = async (
|
||||
});
|
||||
|
||||
return containers || [];
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
|
||||
return [];
|
||||
};
|
||||
@@ -344,7 +340,7 @@ export const containerRestart = async (containerId: string) => {
|
||||
const config = JSON.parse(stdout);
|
||||
|
||||
return config;
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const getSwarmNodes = async (serverId?: string) => {
|
||||
@@ -373,7 +369,7 @@ export const getSwarmNodes = async (serverId?: string) => {
|
||||
.split("\n")
|
||||
.map((line) => JSON.parse(line));
|
||||
return nodesArray;
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const getNodeInfo = async (nodeId: string, serverId?: string) => {
|
||||
@@ -399,7 +395,7 @@ export const getNodeInfo = async (nodeId: string, serverId?: string) => {
|
||||
const nodeInfo = JSON.parse(stdout);
|
||||
|
||||
return nodeInfo;
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const getNodeApplications = async (serverId?: string) => {
|
||||
@@ -431,7 +427,7 @@ export const getNodeApplications = async (serverId?: string) => {
|
||||
.filter((service) => !service.Name.startsWith("dokploy-"));
|
||||
|
||||
return appArray;
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const getApplicationInfo = async (
|
||||
@@ -464,5 +460,5 @@ export const getApplicationInfo = async (
|
||||
.map((line) => JSON.parse(line));
|
||||
|
||||
return appArray;
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { manageDomain } from "@dokploy/server/utils/traefik/domain";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { type apiCreateDomain, domains } from "../db/schema";
|
||||
import { findUserById } from "./admin";
|
||||
import { findAdmin, findAdminById } from "./admin";
|
||||
import { findApplicationById } from "./application";
|
||||
import { findServerById } from "./server";
|
||||
|
||||
@@ -40,7 +40,7 @@ export const createDomain = async (input: typeof apiCreateDomain._type) => {
|
||||
|
||||
export const generateTraefikMeDomain = async (
|
||||
appName: string,
|
||||
userId: string,
|
||||
adminId: string,
|
||||
serverId?: string,
|
||||
) => {
|
||||
if (serverId) {
|
||||
@@ -57,7 +57,7 @@ export const generateTraefikMeDomain = async (
|
||||
projectName: appName,
|
||||
});
|
||||
}
|
||||
const admin = await findUserById(userId);
|
||||
const admin = await findAdminById(adminId);
|
||||
return generateRandomDomain({
|
||||
serverIp: admin?.serverIp || "",
|
||||
projectName: appName,
|
||||
@@ -126,6 +126,7 @@ export const updateDomainById = async (
|
||||
|
||||
export const removeDomainById = async (domainId: string) => {
|
||||
await findDomainById(domainId);
|
||||
// TODO: fix order
|
||||
const result = await db
|
||||
.delete(domains)
|
||||
.where(eq(domains.domainId, domainId))
|
||||
|
||||
@@ -12,14 +12,14 @@ import { updatePreviewDeployment } from "./preview-deployment";
|
||||
export type Github = typeof github.$inferSelect;
|
||||
export const createGithub = async (
|
||||
input: typeof apiCreateGithub._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const newGitProvider = await tx
|
||||
.insert(gitProvider)
|
||||
.values({
|
||||
providerType: "github",
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
name: input.name,
|
||||
})
|
||||
.returning()
|
||||
@@ -119,7 +119,7 @@ export const issueCommentExists = async ({
|
||||
comment_id: comment_id,
|
||||
});
|
||||
return true;
|
||||
} catch (_error) {
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { db } from "@dokploy/server/db";
|
||||
import {
|
||||
type apiCreateGitlab,
|
||||
type bitbucket,
|
||||
gitProvider,
|
||||
type github,
|
||||
gitlab,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
@@ -11,14 +13,14 @@ export type Gitlab = typeof gitlab.$inferSelect;
|
||||
|
||||
export const createGitlab = async (
|
||||
input: typeof apiCreateGitlab._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const newGitProvider = await tx
|
||||
.insert(gitProvider)
|
||||
.values({
|
||||
providerType: "gitlab",
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
name: input.name,
|
||||
})
|
||||
.returning()
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
backups,
|
||||
mariadb,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { buildAppName } from "@dokploy/server/db/schema";
|
||||
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
|
||||
import { generatePassword } from "@dokploy/server/templates/utils";
|
||||
import { buildMariadb } from "@dokploy/server/utils/databases/mariadb";
|
||||
import { pullImage } from "@dokploy/server/utils/docker/utils";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { db } from "@dokploy/server/db";
|
||||
import { type apiCreateMongo, backups, mongo } from "@dokploy/server/db/schema";
|
||||
import { buildAppName } from "@dokploy/server/db/schema";
|
||||
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
|
||||
import { generatePassword } from "@dokploy/server/templates/utils";
|
||||
import { buildMongo } from "@dokploy/server/utils/databases/mongo";
|
||||
import { pullImage } from "@dokploy/server/utils/docker/utils";
|
||||
|
||||
@@ -64,7 +64,7 @@ export const createMount = async (input: typeof apiCreateMount._type) => {
|
||||
console.log(error);
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: `Error ${error instanceof Error ? error.message : error}`,
|
||||
message: "Error creating the mount",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
@@ -91,7 +91,7 @@ export const createFileMount = async (mountId: string) => {
|
||||
console.log(`Error creating the file mount: ${error}`);
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: `Error creating the mount ${error instanceof Error ? error.message : error}`,
|
||||
message: "Error creating the mount",
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
@@ -123,8 +123,8 @@ export const updateMount = async (
|
||||
mountId: string,
|
||||
mountData: Partial<Mount>,
|
||||
) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const mount = await tx
|
||||
return await db.transaction(async (transaction) => {
|
||||
const mount = await db
|
||||
.update(mounts)
|
||||
.set({
|
||||
...mountData,
|
||||
@@ -211,7 +211,7 @@ export const deleteFileMount = async (mountId: string) => {
|
||||
} else {
|
||||
await removeFileOrDirectory(fullPath);
|
||||
}
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
export const getBaseFilesPath = async (mountId: string) => {
|
||||
|
||||
@@ -24,7 +24,7 @@ export type Notification = typeof notifications.$inferSelect;
|
||||
|
||||
export const createSlackNotification = async (
|
||||
input: typeof apiCreateSlack._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
await db.transaction(async (tx) => {
|
||||
const newSlack = await tx
|
||||
@@ -54,8 +54,7 @@ export const createSlackNotification = async (
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
notificationType: "slack",
|
||||
organizationId: organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -84,8 +83,7 @@ export const updateSlackNotification = async (
|
||||
databaseBackup: input.databaseBackup,
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
organizationId: input.organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: input.adminId,
|
||||
})
|
||||
.where(eq(notifications.notificationId, input.notificationId))
|
||||
.returning()
|
||||
@@ -114,7 +112,7 @@ export const updateSlackNotification = async (
|
||||
|
||||
export const createTelegramNotification = async (
|
||||
input: typeof apiCreateTelegram._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
await db.transaction(async (tx) => {
|
||||
const newTelegram = await tx
|
||||
@@ -122,7 +120,6 @@ export const createTelegramNotification = async (
|
||||
.values({
|
||||
botToken: input.botToken,
|
||||
chatId: input.chatId,
|
||||
messageThreadId: input.messageThreadId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -145,8 +142,7 @@ export const createTelegramNotification = async (
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
notificationType: "telegram",
|
||||
organizationId: organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -175,8 +171,7 @@ export const updateTelegramNotification = async (
|
||||
databaseBackup: input.databaseBackup,
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
organizationId: input.organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: input.adminId,
|
||||
})
|
||||
.where(eq(notifications.notificationId, input.notificationId))
|
||||
.returning()
|
||||
@@ -194,7 +189,6 @@ export const updateTelegramNotification = async (
|
||||
.set({
|
||||
botToken: input.botToken,
|
||||
chatId: input.chatId,
|
||||
messageThreadId: input.messageThreadId,
|
||||
})
|
||||
.where(eq(telegram.telegramId, input.telegramId))
|
||||
.returning()
|
||||
@@ -206,7 +200,7 @@ export const updateTelegramNotification = async (
|
||||
|
||||
export const createDiscordNotification = async (
|
||||
input: typeof apiCreateDiscord._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
await db.transaction(async (tx) => {
|
||||
const newDiscord = await tx
|
||||
@@ -236,8 +230,7 @@ export const createDiscordNotification = async (
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
notificationType: "discord",
|
||||
organizationId: organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -266,8 +259,7 @@ export const updateDiscordNotification = async (
|
||||
databaseBackup: input.databaseBackup,
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
organizationId: input.organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: input.adminId,
|
||||
})
|
||||
.where(eq(notifications.notificationId, input.notificationId))
|
||||
.returning()
|
||||
@@ -296,7 +288,7 @@ export const updateDiscordNotification = async (
|
||||
|
||||
export const createEmailNotification = async (
|
||||
input: typeof apiCreateEmail._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
await db.transaction(async (tx) => {
|
||||
const newEmail = await tx
|
||||
@@ -330,8 +322,7 @@ export const createEmailNotification = async (
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
notificationType: "email",
|
||||
organizationId: organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -360,8 +351,7 @@ export const updateEmailNotification = async (
|
||||
databaseBackup: input.databaseBackup,
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
organizationId: input.organizationId,
|
||||
serverThreshold: input.serverThreshold,
|
||||
adminId: input.adminId,
|
||||
})
|
||||
.where(eq(notifications.notificationId, input.notificationId))
|
||||
.returning()
|
||||
@@ -394,7 +384,7 @@ export const updateEmailNotification = async (
|
||||
|
||||
export const createGotifyNotification = async (
|
||||
input: typeof apiCreateGotify._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
await db.transaction(async (tx) => {
|
||||
const newGotify = await tx
|
||||
@@ -426,7 +416,7 @@ export const createGotifyNotification = async (
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
notificationType: "gotify",
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -455,7 +445,7 @@ export const updateGotifyNotification = async (
|
||||
databaseBackup: input.databaseBackup,
|
||||
dokployRestart: input.dokployRestart,
|
||||
dockerCleanup: input.dockerCleanup,
|
||||
organizationId: input.organizationId,
|
||||
adminId: input.adminId,
|
||||
})
|
||||
.where(eq(notifications.notificationId, input.notificationId))
|
||||
.returning()
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
backups,
|
||||
postgres,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { buildAppName } from "@dokploy/server/db/schema";
|
||||
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
|
||||
import { generatePassword } from "@dokploy/server/templates/utils";
|
||||
import { buildPostgres } from "@dokploy/server/utils/databases/postgres";
|
||||
import { pullImage } from "@dokploy/server/utils/docker/utils";
|
||||
|
||||
@@ -2,20 +2,23 @@ import { db } from "@dokploy/server/db";
|
||||
import {
|
||||
type apiCreatePreviewDeployment,
|
||||
deployments,
|
||||
organization,
|
||||
previewDeployments,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { and, desc, eq } from "drizzle-orm";
|
||||
import { generatePassword } from "../templates/utils";
|
||||
import { slugify } from "../setup/server-setup";
|
||||
import { generatePassword, generateRandomDomain } from "../templates/utils";
|
||||
import { removeService } from "../utils/docker/utils";
|
||||
import { removeDirectoryCode } from "../utils/filesystem/directory";
|
||||
import { authGithub } from "../utils/providers/github";
|
||||
import { removeTraefikConfig } from "../utils/traefik/application";
|
||||
import { manageDomain } from "../utils/traefik/domain";
|
||||
import { findUserById } from "./admin";
|
||||
import { findAdminById } from "./admin";
|
||||
import { findApplicationById } from "./application";
|
||||
import { removeDeploymentsByPreviewDeploymentId } from "./deployment";
|
||||
import {
|
||||
removeDeployments,
|
||||
removeDeploymentsByPreviewDeploymentId,
|
||||
} from "./deployment";
|
||||
import { createDomain } from "./domain";
|
||||
import { type Github, getIssueComment } from "./github";
|
||||
|
||||
@@ -103,17 +106,13 @@ export const removePreviewDeployment = async (previewDeploymentId: string) => {
|
||||
for (const operation of cleanupOperations) {
|
||||
try {
|
||||
await operation();
|
||||
} catch (_error) {}
|
||||
} catch (error) {}
|
||||
}
|
||||
return deployment[0];
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Error deleting this preview deployment";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error deleting this preview deployment",
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -155,14 +154,11 @@ export const createPreviewDeployment = async (
|
||||
const application = await findApplicationById(schema.applicationId);
|
||||
const appName = `preview-${application.appName}-${generatePassword(6)}`;
|
||||
|
||||
const org = await db.query.organization.findFirst({
|
||||
where: eq(organization.id, application.project.organizationId),
|
||||
});
|
||||
const generateDomain = await generateWildcardDomain(
|
||||
application.previewWildcard || "*.traefik.me",
|
||||
appName,
|
||||
application.server?.ipAddress || "",
|
||||
org?.ownerId || "",
|
||||
application.project.adminId,
|
||||
);
|
||||
|
||||
const octokit = authGithub(application?.github as Github);
|
||||
@@ -254,7 +250,7 @@ const generateWildcardDomain = async (
|
||||
baseDomain: string,
|
||||
appName: string,
|
||||
serverIp: string,
|
||||
userId: string,
|
||||
adminId: string,
|
||||
): Promise<string> => {
|
||||
if (!baseDomain.startsWith("*.")) {
|
||||
throw new Error('The base domain must start with "*."');
|
||||
@@ -272,7 +268,7 @@ const generateWildcardDomain = async (
|
||||
}
|
||||
|
||||
if (!ip) {
|
||||
const admin = await findUserById(userId);
|
||||
const admin = await findAdminById(adminId);
|
||||
ip = admin?.serverIp || "";
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ export type Project = typeof projects.$inferSelect;
|
||||
|
||||
export const createProject = async (
|
||||
input: typeof apiCreateProject._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
const newProject = await db
|
||||
.insert(projects)
|
||||
.values({
|
||||
...input,
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
updateRedirectMiddleware,
|
||||
} from "@dokploy/server/utils/traefik/redirect";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { desc, eq } from "drizzle-orm";
|
||||
import type { z } from "zod";
|
||||
import { findApplicationById } from "./application";
|
||||
export type Redirect = typeof redirects.$inferSelect;
|
||||
@@ -114,11 +114,9 @@ export const updateRedirectById = async (
|
||||
|
||||
return redirect;
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Error updating this redirect";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error updating this redirect",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { db } from "@dokploy/server/db";
|
||||
import { type apiCreateRedis, redis } from "@dokploy/server/db/schema";
|
||||
import { buildAppName } from "@dokploy/server/db/schema";
|
||||
import { buildAppName, cleanAppName } from "@dokploy/server/db/schema";
|
||||
import { generatePassword } from "@dokploy/server/templates/utils";
|
||||
import { buildRedis } from "@dokploy/server/utils/databases/redis";
|
||||
import { pullImage } from "@dokploy/server/utils/docker/utils";
|
||||
|
||||
@@ -12,14 +12,14 @@ export type Registry = typeof registry.$inferSelect;
|
||||
|
||||
export const createRegistry = async (
|
||||
input: typeof apiCreateRegistry._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
return await db.transaction(async (tx) => {
|
||||
const newRegistry = await tx
|
||||
.insert(registry)
|
||||
.values({
|
||||
...input,
|
||||
organizationId: organizationId,
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -112,11 +112,9 @@ export const updateRegistry = async (
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Error updating this registry";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error updating this registry",
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -137,11 +135,9 @@ export const findRegistryById = async (registryId: string) => {
|
||||
return registryResponse;
|
||||
};
|
||||
|
||||
export const findAllRegistryByOrganizationId = async (
|
||||
organizationId: string,
|
||||
) => {
|
||||
export const findAllRegistryByAdminId = async (adminId: string) => {
|
||||
const registryResponse = await db.query.registry.findMany({
|
||||
where: eq(registry.organizationId, organizationId),
|
||||
where: eq(registry.adminId, adminId),
|
||||
});
|
||||
return registryResponse;
|
||||
};
|
||||
|
||||
@@ -76,11 +76,9 @@ export const deleteSecurityById = async (securityId: string) => {
|
||||
await removeSecurityMiddleware(application, result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Error removing this security";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error removing this security",
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -100,11 +98,9 @@ export const updateSecurityById = async (
|
||||
|
||||
return response[0];
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Error updating this security";
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message,
|
||||
message: "Error updating this security",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
import { db } from "@dokploy/server/db";
|
||||
import {
|
||||
type apiCreateServer,
|
||||
organization,
|
||||
server,
|
||||
} from "@dokploy/server/db/schema";
|
||||
import { type apiCreateServer, server } from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { desc, eq } from "drizzle-orm";
|
||||
|
||||
export type Server = typeof server.$inferSelect;
|
||||
|
||||
export const createServer = async (
|
||||
input: typeof apiCreateServer._type,
|
||||
organizationId: string,
|
||||
adminId: string,
|
||||
) => {
|
||||
const newServer = await db
|
||||
.insert(server)
|
||||
.values({
|
||||
...input,
|
||||
organizationId: organizationId,
|
||||
createdAt: new Date().toISOString(),
|
||||
adminId: adminId,
|
||||
})
|
||||
.returning()
|
||||
.then((value) => value[0]);
|
||||
@@ -50,16 +45,12 @@ export const findServerById = async (serverId: string) => {
|
||||
return currentServer;
|
||||
};
|
||||
|
||||
export const findServersByUserId = async (userId: string) => {
|
||||
const orgs = await db.query.organization.findMany({
|
||||
where: eq(organization.ownerId, userId),
|
||||
with: {
|
||||
servers: true,
|
||||
},
|
||||
export const findServersByAdminId = async (adminId: string) => {
|
||||
const servers = await db.query.server.findMany({
|
||||
where: eq(server.adminId, adminId),
|
||||
orderBy: desc(server.createdAt),
|
||||
});
|
||||
|
||||
const servers = orgs.flatMap((org) => org.servers);
|
||||
|
||||
return servers;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
execAsync,
|
||||
execAsyncRemote,
|
||||
} from "@dokploy/server/utils/process/execAsync";
|
||||
// import packageInfo from "../../../package.json";
|
||||
|
||||
export interface IUpdateData {
|
||||
latestVersion: string | null;
|
||||
@@ -169,6 +170,7 @@ echo "$json_output"
|
||||
const result = JSON.parse(stdout);
|
||||
return result;
|
||||
}
|
||||
const items = readdirSync(dirPath, { withFileTypes: true });
|
||||
|
||||
const stack = [dirPath];
|
||||
const result: TreeDataItem[] = [];
|
||||
@@ -211,35 +213,3 @@ echo "$json_output"
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const cleanupFullDocker = async (serverId?: string | null) => {
|
||||
const cleanupImages = "docker image prune --force";
|
||||
const cleanupVolumes = "docker volume prune --force";
|
||||
const cleanupContainers = "docker container prune --force";
|
||||
const cleanupSystem = "docker system prune --force --volumes";
|
||||
const cleanupBuilder = "docker builder prune --force";
|
||||
|
||||
try {
|
||||
if (serverId) {
|
||||
await execAsyncRemote(
|
||||
serverId,
|
||||
`
|
||||
${cleanupImages}
|
||||
${cleanupVolumes}
|
||||
${cleanupContainers}
|
||||
${cleanupSystem}
|
||||
${cleanupBuilder}
|
||||
`,
|
||||
);
|
||||
}
|
||||
await execAsync(`
|
||||
${cleanupImages}
|
||||
${cleanupVolumes}
|
||||
${cleanupContainers}
|
||||
${cleanupSystem}
|
||||
${cleanupBuilder}
|
||||
`);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,53 +1,80 @@
|
||||
import { db } from "@dokploy/server/db";
|
||||
import { apikey, member, users_temp } from "@dokploy/server/db/schema";
|
||||
import { users } from "@dokploy/server/db/schema";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { auth } from "../lib/auth";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export type User = typeof users_temp.$inferSelect;
|
||||
export type User = typeof users.$inferSelect;
|
||||
|
||||
export const addNewProject = async (
|
||||
userId: string,
|
||||
projectId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const userR = await findMemberById(userId, organizationId);
|
||||
|
||||
await db
|
||||
.update(member)
|
||||
.set({
|
||||
accessedProjects: [...userR.accessedProjects, projectId],
|
||||
})
|
||||
.where(
|
||||
and(eq(member.id, userR.id), eq(member.organizationId, organizationId)),
|
||||
);
|
||||
export const findUserById = async (userId: string) => {
|
||||
const user = await db.query.users.findFirst({
|
||||
where: eq(users.userId, userId),
|
||||
});
|
||||
if (!user) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "User not found",
|
||||
});
|
||||
}
|
||||
return user;
|
||||
};
|
||||
|
||||
export const addNewService = async (
|
||||
userId: string,
|
||||
serviceId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const userR = await findMemberById(userId, organizationId);
|
||||
export const findUserByAuthId = async (authId: string) => {
|
||||
const user = await db.query.users.findFirst({
|
||||
where: eq(users.authId, authId),
|
||||
with: {
|
||||
auth: true,
|
||||
},
|
||||
});
|
||||
if (!user) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "User not found",
|
||||
});
|
||||
}
|
||||
return user;
|
||||
};
|
||||
|
||||
export const findUsers = async (adminId: string) => {
|
||||
const currentUsers = await db.query.users.findMany({
|
||||
where: eq(users.adminId, adminId),
|
||||
with: {
|
||||
auth: {
|
||||
columns: {
|
||||
secret: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return currentUsers;
|
||||
};
|
||||
|
||||
export const addNewProject = async (authId: string, projectId: string) => {
|
||||
const user = await findUserByAuthId(authId);
|
||||
|
||||
await db
|
||||
.update(member)
|
||||
.update(users)
|
||||
.set({
|
||||
accessedServices: [...userR.accessedServices, serviceId],
|
||||
accessedProjects: [...user.accessedProjects, projectId],
|
||||
})
|
||||
.where(
|
||||
and(eq(member.id, userR.id), eq(member.organizationId, organizationId)),
|
||||
);
|
||||
.where(eq(users.authId, authId));
|
||||
};
|
||||
|
||||
export const addNewService = async (authId: string, serviceId: string) => {
|
||||
const user = await findUserByAuthId(authId);
|
||||
await db
|
||||
.update(users)
|
||||
.set({
|
||||
accessedServices: [...user.accessedServices, serviceId],
|
||||
})
|
||||
.where(eq(users.authId, authId));
|
||||
};
|
||||
|
||||
export const canPerformCreationService = async (
|
||||
userId: string,
|
||||
projectId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { accessedProjects, canCreateServices } = await findMemberById(
|
||||
userId,
|
||||
organizationId,
|
||||
);
|
||||
const { accessedProjects, canCreateServices } =
|
||||
await findUserByAuthId(userId);
|
||||
const haveAccessToProject = accessedProjects.includes(projectId);
|
||||
|
||||
if (canCreateServices && haveAccessToProject) {
|
||||
@@ -60,9 +87,8 @@ export const canPerformCreationService = async (
|
||||
export const canPerformAccessService = async (
|
||||
userId: string,
|
||||
serviceId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { accessedServices } = await findMemberById(userId, organizationId);
|
||||
const { accessedServices } = await findUserByAuthId(userId);
|
||||
const haveAccessToService = accessedServices.includes(serviceId);
|
||||
|
||||
if (haveAccessToService) {
|
||||
@@ -73,14 +99,11 @@ export const canPerformAccessService = async (
|
||||
};
|
||||
|
||||
export const canPeformDeleteService = async (
|
||||
userId: string,
|
||||
authId: string,
|
||||
serviceId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { accessedServices, canDeleteServices } = await findMemberById(
|
||||
userId,
|
||||
organizationId,
|
||||
);
|
||||
const { accessedServices, canDeleteServices } =
|
||||
await findUserByAuthId(authId);
|
||||
const haveAccessToService = accessedServices.includes(serviceId);
|
||||
|
||||
if (canDeleteServices && haveAccessToService) {
|
||||
@@ -90,11 +113,8 @@ export const canPeformDeleteService = async (
|
||||
return false;
|
||||
};
|
||||
|
||||
export const canPerformCreationProject = async (
|
||||
userId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { canCreateProjects } = await findMemberById(userId, organizationId);
|
||||
export const canPerformCreationProject = async (authId: string) => {
|
||||
const { canCreateProjects } = await findUserByAuthId(authId);
|
||||
|
||||
if (canCreateProjects) {
|
||||
return true;
|
||||
@@ -103,11 +123,8 @@ export const canPerformCreationProject = async (
|
||||
return false;
|
||||
};
|
||||
|
||||
export const canPerformDeleteProject = async (
|
||||
userId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { canDeleteProjects } = await findMemberById(userId, organizationId);
|
||||
export const canPerformDeleteProject = async (authId: string) => {
|
||||
const { canDeleteProjects } = await findUserByAuthId(authId);
|
||||
|
||||
if (canDeleteProjects) {
|
||||
return true;
|
||||
@@ -117,11 +134,10 @@ export const canPerformDeleteProject = async (
|
||||
};
|
||||
|
||||
export const canPerformAccessProject = async (
|
||||
userId: string,
|
||||
authId: string,
|
||||
projectId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { accessedProjects } = await findMemberById(userId, organizationId);
|
||||
const { accessedProjects } = await findUserByAuthId(authId);
|
||||
|
||||
const haveAccessToProject = accessedProjects.includes(projectId);
|
||||
|
||||
@@ -131,45 +147,26 @@ export const canPerformAccessProject = async (
|
||||
return false;
|
||||
};
|
||||
|
||||
export const canAccessToTraefikFiles = async (
|
||||
userId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const { canAccessToTraefikFiles } = await findMemberById(
|
||||
userId,
|
||||
organizationId,
|
||||
);
|
||||
export const canAccessToTraefikFiles = async (authId: string) => {
|
||||
const { canAccessToTraefikFiles } = await findUserByAuthId(authId);
|
||||
return canAccessToTraefikFiles;
|
||||
};
|
||||
|
||||
export const checkServiceAccess = async (
|
||||
userId: string,
|
||||
authId: string,
|
||||
serviceId: string,
|
||||
organizationId: string,
|
||||
action = "access" as "access" | "create" | "delete",
|
||||
) => {
|
||||
let hasPermission = false;
|
||||
switch (action) {
|
||||
case "create":
|
||||
hasPermission = await canPerformCreationService(
|
||||
userId,
|
||||
serviceId,
|
||||
organizationId,
|
||||
);
|
||||
hasPermission = await canPerformCreationService(authId, serviceId);
|
||||
break;
|
||||
case "access":
|
||||
hasPermission = await canPerformAccessService(
|
||||
userId,
|
||||
serviceId,
|
||||
organizationId,
|
||||
);
|
||||
hasPermission = await canPerformAccessService(authId, serviceId);
|
||||
break;
|
||||
case "delete":
|
||||
hasPermission = await canPeformDeleteService(
|
||||
userId,
|
||||
serviceId,
|
||||
organizationId,
|
||||
);
|
||||
hasPermission = await canPeformDeleteService(authId, serviceId);
|
||||
break;
|
||||
default:
|
||||
hasPermission = false;
|
||||
@@ -185,7 +182,6 @@ export const checkServiceAccess = async (
|
||||
export const checkProjectAccess = async (
|
||||
authId: string,
|
||||
action: "create" | "delete" | "access",
|
||||
organizationId: string,
|
||||
projectId?: string,
|
||||
) => {
|
||||
let hasPermission = false;
|
||||
@@ -194,14 +190,13 @@ export const checkProjectAccess = async (
|
||||
hasPermission = await canPerformAccessProject(
|
||||
authId,
|
||||
projectId as string,
|
||||
organizationId,
|
||||
);
|
||||
break;
|
||||
case "create":
|
||||
hasPermission = await canPerformCreationProject(authId, organizationId);
|
||||
hasPermission = await canPerformCreationProject(authId);
|
||||
break;
|
||||
case "delete":
|
||||
hasPermission = await canPerformDeleteProject(authId, organizationId);
|
||||
hasPermission = await canPerformDeleteProject(authId);
|
||||
break;
|
||||
default:
|
||||
hasPermission = false;
|
||||
@@ -213,82 +208,3 @@ export const checkProjectAccess = async (
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const findMemberById = async (
|
||||
userId: string,
|
||||
organizationId: string,
|
||||
) => {
|
||||
const result = await db.query.member.findFirst({
|
||||
where: and(
|
||||
eq(member.userId, userId),
|
||||
eq(member.organizationId, organizationId),
|
||||
),
|
||||
with: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "Permission denied",
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const updateUser = async (userId: string, userData: Partial<User>) => {
|
||||
const user = await db
|
||||
.update(users_temp)
|
||||
.set({
|
||||
...userData,
|
||||
})
|
||||
.where(eq(users_temp.id, userId))
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
export const createApiKey = async (
|
||||
userId: string,
|
||||
input: {
|
||||
name: string;
|
||||
prefix?: string;
|
||||
expiresIn?: number;
|
||||
metadata: {
|
||||
organizationId: string;
|
||||
};
|
||||
rateLimitEnabled?: boolean;
|
||||
rateLimitTimeWindow?: number;
|
||||
rateLimitMax?: number;
|
||||
remaining?: number;
|
||||
refillAmount?: number;
|
||||
refillInterval?: number;
|
||||
},
|
||||
) => {
|
||||
const apiKey = await auth.createApiKey({
|
||||
body: {
|
||||
name: input.name,
|
||||
expiresIn: input.expiresIn,
|
||||
prefix: input.prefix,
|
||||
rateLimitEnabled: input.rateLimitEnabled,
|
||||
rateLimitTimeWindow: input.rateLimitTimeWindow,
|
||||
rateLimitMax: input.rateLimitMax,
|
||||
remaining: input.remaining,
|
||||
refillAmount: input.refillAmount,
|
||||
refillInterval: input.refillInterval,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (input.metadata) {
|
||||
await db
|
||||
.update(apikey)
|
||||
.set({
|
||||
metadata: JSON.stringify(input.metadata),
|
||||
})
|
||||
.where(eq(apikey.id, apiKey.id));
|
||||
}
|
||||
return apiKey;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user