Merge branch 'canary' into new-logs

This commit is contained in:
Mauricio Siu
2024-12-15 19:01:26 -06:00
120 changed files with 12687 additions and 1248 deletions

View File

@@ -20,6 +20,8 @@ import {
getUserByToken,
lucia,
luciaToken,
removeAdminByAuthId,
removeUserByAuthId,
sendDiscordNotification,
sendEmailNotification,
updateAuthById,
@@ -59,14 +61,20 @@ export const authRouter = createTRPCRouter({
if (IS_CLOUD) {
await sendDiscordNotificationWelcome(newAdmin);
await sendVerificationEmail(newAdmin.id);
return true;
return {
status: "success",
type: "cloud",
};
}
const session = await lucia.createSession(newAdmin.id || "", {});
ctx.res.appendHeader(
"Set-Cookie",
lucia.createSessionCookie(session.id).serialize(),
);
return true;
return {
status: "success",
type: "selfhosted",
};
} catch (error) {
throw new TRPCError({
code: "BAD_REQUEST",
@@ -178,6 +186,20 @@ export const authRouter = createTRPCRouter({
update: protectedProcedure
.input(apiUpdateAuth)
.mutation(async ({ ctx, input }) => {
const currentAuth = await findAuthByEmail(ctx.user.email);
if (input.password) {
const correctPassword = bcrypt.compareSync(
input.password,
currentAuth?.password || "",
);
if (!correctPassword) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Current password is incorrect",
});
}
}
const auth = await updateAuthById(ctx.user.authId, {
...(input.email && { email: input.email.toLowerCase() }),
...(input.password && {
@@ -188,6 +210,47 @@ export const authRouter = createTRPCRouter({
return auth;
}),
removeSelfAccount: protectedProcedure
.input(
z.object({
password: z.string().min(1),
}),
)
.mutation(async ({ ctx, input }) => {
if (!IS_CLOUD) {
throw new TRPCError({
code: "NOT_FOUND",
message: "This feature is only available in the cloud version",
});
}
const currentAuth = await findAuthByEmail(ctx.user.email);
const correctPassword = bcrypt.compareSync(
input.password,
currentAuth?.password || "",
);
if (!correctPassword) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Password is incorrect",
});
}
const { req, res } = ctx;
const { session } = await validateRequest(req, res);
if (!session) return false;
await lucia.invalidateSession(session.id);
res.setHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
if (ctx.user.rol === "admin") {
await removeAdminByAuthId(ctx.user.authId);
} else {
await removeUserByAuthId(ctx.user.authId);
}
return true;
}),
generateToken: protectedProcedure.mutation(async ({ ctx, input }) => {
const auth = await findAuthById(ctx.user.authId);
@@ -440,7 +503,7 @@ export const sendDiscordNotificationWelcome = async (newAdmin: Auth) => {
webhookUrl: process.env.DISCORD_WEBHOOK_URL || "",
},
{
title: " New User Registered",
title: " New User Registered",
color: 0x00ff00,
fields: [
{

View File

@@ -142,6 +142,10 @@ export const gitlabRouter = createTRPCRouter({
name: input.name,
adminId: ctx.user.adminId,
});
await updateGitlab(input.gitlabId, {
...input,
});
} else {
await updateGitlab(input.gitlabId, {
...input,

View File

@@ -18,6 +18,7 @@ import {
import {
IS_CLOUD,
createServer,
defaultCommand,
deleteServer,
findAdminById,
findServerById,
@@ -69,6 +70,11 @@ export const serverRouter = createTRPCRouter({
return server;
}),
getDefaultCommand: protectedProcedure
.input(apiFindOneServer)
.query(async ({ input, ctx }) => {
return defaultCommand();
}),
all: protectedProcedure.query(async ({ ctx }) => {
const result = await db
.select({

View File

@@ -17,7 +17,7 @@ import {
updateSSHKeyById,
} from "@dokploy/server";
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
import { desc, eq } from "drizzle-orm";
export const sshRouter = createTRPCRouter({
create: protectedProcedure
@@ -71,6 +71,7 @@ export const sshRouter = createTRPCRouter({
all: protectedProcedure.query(async ({ ctx }) => {
return await db.query.sshKeys.findMany({
...(IS_CLOUD && { where: eq(sshKeys.adminId, ctx.user.adminId) }),
orderBy: desc(sshKeys.createdAt),
});
// TODO: Remove this line when the cloud version is ready
}),

View File

@@ -81,7 +81,7 @@ export const stripeRouter = createTRPCRouter({
adminId: admin.adminId,
},
allow_promotion_codes: true,
success_url: `${WEBSITE_URL}/dashboard/settings/billing`,
success_url: `${WEBSITE_URL}/dashboard/settings/servers?success=true`,
cancel_url: `${WEBSITE_URL}/dashboard/settings/billing`,
});

View File

@@ -102,21 +102,13 @@ export const setupDockerContainerTerminalWebSocketServer = (
port: server.port,
username: server.username,
privateKey: server.sshKey?.privateKey,
timeout: 99999,
});
} else {
const shell = getShell();
const ptyProcess = spawn(
shell,
["-c", `docker exec -it ${containerId} ${activeWay}`],
{
name: "xterm-256color",
cwd: process.env.HOME,
env: process.env,
encoding: "utf8",
cols: 80,
rows: 30,
},
{},
);
ptyProcess.onData((data) => {

View File

@@ -70,53 +70,44 @@ export const setupTerminalWebSocketServer = (
let stderr = "";
conn
.once("ready", () => {
conn.shell(
{
term: "terminal",
cols: 80,
rows: 30,
height: 30,
width: 80,
},
(err, stream) => {
if (err) throw err;
conn.shell({}, (err, stream) => {
if (err) throw err;
stream
.on("close", (code: number, signal: string) => {
ws.send(`\nContainer closed with code: ${code}\n`);
conn.end();
})
.on("data", (data: string) => {
stdout += data.toString();
ws.send(data.toString());
})
.stderr.on("data", (data) => {
stderr += data.toString();
ws.send(data.toString());
console.error("Error: ", data.toString());
});
stream
.on("close", (code: number, signal: string) => {
ws.send(`\nContainer closed with code: ${code}\n`);
conn.end();
})
.on("data", (data: string) => {
stdout += data.toString();
ws.send(data.toString());
})
.stderr.on("data", (data) => {
stderr += data.toString();
ws.send(data.toString());
console.error("Error: ", data.toString());
});
ws.on("message", (message) => {
try {
let command: string | Buffer[] | Buffer | ArrayBuffer;
if (Buffer.isBuffer(message)) {
command = message.toString("utf8");
} else {
command = message;
}
stream.write(command.toString());
} catch (error) {
// @ts-ignore
const errorMessage = error?.message as unknown as string;
ws.send(errorMessage);
ws.on("message", (message) => {
try {
let command: string | Buffer[] | Buffer | ArrayBuffer;
if (Buffer.isBuffer(message)) {
command = message.toString("utf8");
} else {
command = message;
}
});
stream.write(command.toString());
} catch (error) {
// @ts-ignore
const errorMessage = error?.message as unknown as string;
ws.send(errorMessage);
}
});
ws.on("close", () => {
stream.end();
});
},
);
ws.on("close", () => {
stream.end();
});
});
})
.on("error", (err) => {
if (err.level === "client-authentication") {
@@ -133,7 +124,6 @@ export const setupTerminalWebSocketServer = (
port: server.port,
username: server.username,
privateKey: server.sshKey?.privateKey,
timeout: 99999,
});
});
};