feat: add migration

This commit is contained in:
Mauricio Siu
2025-02-09 18:19:21 -06:00
parent 6b9fd596e5
commit c04bf3c7e0
31 changed files with 5790 additions and 440 deletions

View File

@@ -0,0 +1,62 @@
import {
pgTable,
text,
integer,
timestamp,
boolean,
} from "drizzle-orm/pg-core";
export const user = pgTable("user", {
id: text("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
emailVerified: boolean("email_verified").notNull(),
image: text("image"),
createdAt: timestamp("created_at").notNull(),
updatedAt: timestamp("updated_at").notNull(),
role: text("role"),
banned: boolean("banned"),
banReason: text("ban_reason"),
banExpires: timestamp("ban_expires"),
});
export const session = pgTable("session", {
id: text("id").primaryKey(),
expiresAt: timestamp("expires_at").notNull(),
token: text("token").notNull().unique(),
createdAt: timestamp("created_at").notNull(),
updatedAt: timestamp("updated_at").notNull(),
ipAddress: text("ip_address"),
userAgent: text("user_agent"),
userId: text("user_id")
.notNull()
.references(() => user.id),
impersonatedBy: text("impersonated_by"),
});
// export const account = pgTable("account", {
// id: text("id").primaryKey(),
// accountId: text("account_id").notNull(),
// providerId: text("provider_id").notNull(),
// userId: text("user_id")
// .notNull()
// .references(() => user.id),
// accessToken: text("access_token"),
// refreshToken: text("refresh_token"),
// idToken: text("id_token"),
// accessTokenExpiresAt: timestamp("access_token_expires_at"),
// refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
// scope: text("scope"),
// password: text("password"),
// createdAt: timestamp("created_at").notNull(),
// updatedAt: timestamp("updated_at").notNull(),
// });
// export const verification = pgTable("verification", {
// id: text("id").primaryKey(),
// identifier: text("identifier").notNull(),
// value: text("value").notNull(),
// expiresAt: timestamp("expires_at").notNull(),
// createdAt: timestamp("created_at"),
// updatedAt: timestamp("updated_at"),
// });

View File

@@ -28,6 +28,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"better-auth":"1.1.16",
"rotating-file-stream": "3.2.3",
"@faker-js/faker": "^8.4.1",
"@lucia-auth/adapter-drizzle": "1.0.7",

View File

@@ -0,0 +1,34 @@
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { users } from "./user";
export const account = pgTable("account", {
id: text("id").primaryKey(),
accountId: text("account_id").notNull(),
providerId: text("provider_id").notNull(),
userId: text("user_id")
.notNull()
.references(() => users.id),
accessToken: text("access_token"),
refreshToken: text("refresh_token"),
idToken: text("id_token"),
accessTokenExpiresAt: timestamp("access_token_expires_at"),
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
scope: text("scope"),
password: text("password"),
is2FAEnabled: boolean("is2FAEnabled").notNull().default(false),
createdAt: timestamp("created_at").notNull(),
updatedAt: timestamp("updated_at").notNull(),
resetPasswordToken: text("resetPasswordToken"),
resetPasswordExpiresAt: text("resetPasswordExpiresAt"),
confirmationToken: text("confirmationToken"),
confirmationExpiresAt: text("confirmationExpiresAt"),
});
export const verification = pgTable("verification", {
id: text("id").primaryKey(),
identifier: text("identifier").notNull(),
value: text("value").notNull(),
expiresAt: timestamp("expires_at").notNull(),
createdAt: timestamp("created_at"),
updatedAt: timestamp("updated_at"),
});

View File

@@ -18,128 +18,127 @@ import { sshKeys } from "./ssh-key";
import { users } from "./user";
export const admins = pgTable("admin", {
adminId: text("adminId")
.notNull()
.primaryKey()
.$defaultFn(() => nanoid()),
serverIp: text("serverIp"),
certificateType: certificateType("certificateType").notNull().default("none"),
host: text("host"),
letsEncryptEmail: text("letsEncryptEmail"),
sshPrivateKey: text("sshPrivateKey"),
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
enableLogRotation: boolean("enableLogRotation").notNull().default(false),
authId: text("authId")
.notNull()
.references(() => auth.id, { onDelete: "cascade" }),
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
stripeCustomerId: text("stripeCustomerId"),
stripeSubscriptionId: text("stripeSubscriptionId"),
serversQuantity: integer("serversQuantity").notNull().default(0),
// Metrics
enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
metricsConfig: jsonb("metricsConfig")
.$type<{
server: {
type: "Dokploy" | "Remote";
refreshRate: number;
port: number;
token: string;
urlCallback: string;
retentionDays: number;
cronJob: string;
thresholds: {
cpu: number;
memory: number;
};
};
containers: {
refreshRate: number;
services: {
include: string[];
exclude: string[];
};
};
}>()
.notNull()
.default({
server: {
type: "Dokploy",
refreshRate: 60,
port: 4500,
token: "",
retentionDays: 2,
cronJob: "",
urlCallback: "",
thresholds: {
cpu: 0,
memory: 0,
},
},
containers: {
refreshRate: 60,
services: {
include: [],
exclude: [],
},
},
}),
cleanupCacheApplications: boolean("cleanupCacheApplications")
.notNull()
.default(false),
cleanupCacheOnPreviews: boolean("cleanupCacheOnPreviews")
.notNull()
.default(false),
cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
.notNull()
.default(false),
// adminId: text("adminId")
// .notNull()
// .primaryKey()
// .$defaultFn(() => nanoid()),
// serverIp: text("serverIp"),
// certificateType: certificateType("certificateType").notNull().default("none"),
// host: text("host"),
// letsEncryptEmail: text("letsEncryptEmail"),
// sshPrivateKey: text("sshPrivateKey"),
// enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
// enableLogRotation: boolean("enableLogRotation").notNull().default(false),
// authId: text("authId")
// .notNull()
// .references(() => auth.id, { onDelete: "cascade" }),
// createdAt: text("createdAt")
// .notNull()
// .$defaultFn(() => new Date().toISOString()),
// stripeCustomerId: text("stripeCustomerId"),
// stripeSubscriptionId: text("stripeSubscriptionId"),
// serversQuantity: integer("serversQuantity").notNull().default(0),
// // Metrics
// enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
// metricsConfig: jsonb("metricsConfig")
// .$type<{
// server: {
// type: "Dokploy" | "Remote";
// refreshRate: number;
// port: number;
// token: string;
// urlCallback: string;
// retentionDays: number;
// cronJob: string;
// thresholds: {
// cpu: number;
// memory: number;
// };
// };
// containers: {
// refreshRate: number;
// services: {
// include: string[];
// exclude: string[];
// };
// };
// }>()
// .notNull()
// .default({
// server: {
// type: "Dokploy",
// refreshRate: 60,
// port: 4500,
// token: "",
// retentionDays: 2,
// cronJob: "",
// urlCallback: "",
// thresholds: {
// cpu: 0,
// memory: 0,
// },
// },
// containers: {
// refreshRate: 60,
// services: {
// include: [],
// exclude: [],
// },
// },
// }),
// cleanupCacheApplications: boolean("cleanupCacheApplications")
// .notNull()
// .default(false),
// cleanupCacheOnPreviews: boolean("cleanupCacheOnPreviews")
// .notNull()
// .default(false),
// cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
// .notNull()
// .default(false),
});
export const adminsRelations = relations(admins, ({ one, many }) => ({
auth: one(auth, {
fields: [admins.authId],
references: [auth.id],
}),
users: many(users),
registry: many(registry),
sshKeys: many(sshKeys),
certificates: many(certificates),
// auth: one(auth, {
// fields: [admins.authId],
// references: [auth.id],
// }),
// users: many(users),
// registry: many(registry),
// sshKeys: many(sshKeys),
// certificates: many(certificates),
}));
const createSchema = createInsertSchema(admins, {
adminId: z.string(),
enableDockerCleanup: z.boolean().optional(),
sshPrivateKey: z.string().optional(),
certificateType: z.enum(["letsencrypt", "none"]).default("none"),
serverIp: z.string().optional(),
letsEncryptEmail: z.string().optional(),
// adminId: z.string(),
// enableDockerCleanup: z.boolean().optional(),
// sshPrivateKey: z.string().optional(),
// certificateType: z.enum(["letsencrypt", "none"]).default("none"),
// serverIp: z.string().optional(),
// letsEncryptEmail: z.string().optional(),
});
export const apiUpdateAdmin = createSchema.partial();
export const apiSaveSSHKey = createSchema
.pick({
sshPrivateKey: true,
// sshPrivateKey: true,
})
.required();
export const apiAssignDomain = createSchema
.pick({
host: true,
certificateType: true,
letsEncryptEmail: true,
// host: true,
// certificateType: true,
// letsEncryptEmail: true,
})
.required()
.partial({
letsEncryptEmail: true,
// letsEncryptEmail: true,
});
export const apiUpdateDockerCleanup = createSchema
.pick({
enableDockerCleanup: true,
// enableDockerCleanup: true,
})
.required()
.extend({

View File

@@ -4,7 +4,7 @@ import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
// import { admins } from "./admin";
import { users } from "./user";
const randomImages = [
@@ -55,7 +55,7 @@ export const auth = pgTable("auth", {
});
export const authRelations = relations(auth, ({ many }) => ({
admins: many(admins),
// admins: many(admins),
users: many(users),
}));
const createSchema = createInsertSchema(auth, {

View File

@@ -3,9 +3,9 @@ import { boolean, pgTable, text } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
import { server } from "./server";
import { generateAppName } from "./utils";
import { users } from "./user";
export const certificates = pgTable("certificate", {
certificateId: text("certificateId")
@@ -20,7 +20,7 @@ export const certificates = pgTable("certificate", {
.$defaultFn(() => generateAppName("certificate"))
.unique(),
autoRenew: boolean("autoRenew"),
adminId: text("adminId").references(() => admins.adminId, {
userId: text("userId").references(() => users.id, {
onDelete: "cascade",
}),
serverId: text("serverId").references(() => server.serverId, {
@@ -35,9 +35,9 @@ export const certificatesRelations = relations(
fields: [certificates.serverId],
references: [server.serverId],
}),
admin: one(admins, {
fields: [certificates.adminId],
references: [admins.adminId],
user: one(users, {
fields: [certificates.userId],
references: [users.id],
}),
}),
);

View File

@@ -5,6 +5,7 @@ import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
import { backups } from "./backups";
import { users } from "./user";
export const destinations = pgTable("destination", {
destinationId: text("destinationId")
@@ -19,18 +20,18 @@ export const destinations = pgTable("destination", {
region: text("region").notNull(),
// maybe it can be null
endpoint: text("endpoint").notNull(),
adminId: text("adminId")
userId: text("userId")
.notNull()
.references(() => admins.adminId, { onDelete: "cascade" }),
.references(() => users.id, { onDelete: "cascade" }),
});
export const destinationsRelations = relations(
destinations,
({ many, one }) => ({
backups: many(backups),
admin: one(admins, {
fields: [destinations.adminId],
references: [admins.adminId],
user: one(users, {
fields: [destinations.userId],
references: [users.id],
}),
}),
);

View File

@@ -7,6 +7,7 @@ import { admins } from "./admin";
import { bitbucket } from "./bitbucket";
import { github } from "./github";
import { gitlab } from "./gitlab";
import { users } from "./user";
export const gitProviderType = pgEnum("gitProviderType", [
"github",
@@ -24,7 +25,7 @@ export const gitProvider = pgTable("git_provider", {
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
adminId: text("adminId").references(() => admins.adminId, {
userId: text("userId").references(() => users.id, {
onDelete: "cascade",
}),
});
@@ -42,9 +43,9 @@ export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
fields: [gitProvider.gitProviderId],
references: [bitbucket.gitProviderId],
}),
admin: one(admins, {
fields: [gitProvider.adminId],
references: [admins.adminId],
user: one(users, {
fields: [gitProvider.userId],
references: [users.id],
}),
}));

View File

@@ -30,3 +30,4 @@ export * from "./gitlab";
export * from "./server";
export * from "./utils";
export * from "./preview-deployments";
export * from "./account";

View File

@@ -4,6 +4,7 @@ import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
import { users } from "./user";
export const notificationType = pgEnum("notificationType", [
"slack",
@@ -44,7 +45,7 @@ export const notifications = pgTable("notification", {
gotifyId: text("gotifyId").references(() => gotify.gotifyId, {
onDelete: "cascade",
}),
adminId: text("adminId").references(() => admins.adminId, {
userId: text("userId").references(() => users.id, {
onDelete: "cascade",
}),
});
@@ -121,9 +122,9 @@ export const notificationsRelations = relations(notifications, ({ one }) => ({
fields: [notifications.gotifyId],
references: [gotify.gotifyId],
}),
admin: one(admins, {
fields: [notifications.adminId],
references: [admins.adminId],
user: one(users, {
fields: [notifications.userId],
references: [users.id],
}),
}));

View File

@@ -4,7 +4,7 @@ import { pgTable, text } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
// import { admins } from "./admin";
import { applications } from "./application";
import { compose } from "./compose";
import { mariadb } from "./mariadb";
@@ -12,6 +12,7 @@ import { mongo } from "./mongo";
import { mysql } from "./mysql";
import { postgres } from "./postgres";
import { redis } from "./redis";
import { users } from "./user";
export const projects = pgTable("project", {
projectId: text("projectId")
@@ -23,9 +24,9 @@ export const projects = pgTable("project", {
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
adminId: text("adminId")
userId: text("userId")
.notNull()
.references(() => admins.adminId, { onDelete: "cascade" }),
.references(() => users.id, { onDelete: "cascade" }),
env: text("env").notNull().default(""),
});
@@ -37,9 +38,9 @@ export const projectRelations = relations(projects, ({ many, one }) => ({
mongo: many(mongo),
redis: many(redis),
compose: many(compose),
admin: one(admins, {
fields: [projects.adminId],
references: [admins.adminId],
user: one(users, {
fields: [projects.userId],
references: [users.id],
}),
}));

View File

@@ -5,6 +5,7 @@ import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
import { applications } from "./application";
import { users } from "./user";
/**
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
* database instance for multiple projects.
@@ -27,15 +28,15 @@ export const registry = pgTable("registry", {
.notNull()
.$defaultFn(() => new Date().toISOString()),
registryType: registryType("selfHosted").notNull().default("cloud"),
adminId: text("adminId")
userId: text("userId")
.notNull()
.references(() => admins.adminId, { onDelete: "cascade" }),
.references(() => users.id, { onDelete: "cascade" }),
});
export const registryRelations = relations(registry, ({ one, many }) => ({
admin: one(admins, {
fields: [registry.adminId],
references: [admins.adminId],
user: one(users, {
fields: [registry.userId],
references: [users.id],
}),
applications: many(applications),
}));
@@ -45,7 +46,7 @@ const createSchema = createInsertSchema(registry, {
username: z.string().min(1),
password: z.string().min(1),
registryUrl: z.string(),
adminId: z.string().min(1),
userId: z.string().min(1),
registryId: z.string().min(1),
registryType: z.enum(["cloud"]),
imagePrefix: z.string().nullable().optional(),

View File

@@ -23,6 +23,7 @@ import { postgres } from "./postgres";
import { redis } from "./redis";
import { sshKeys } from "./ssh-key";
import { generateAppName } from "./utils";
import { users } from "./user";
export const serverStatus = pgEnum("serverStatus", ["active", "inactive"]);
@@ -43,9 +44,9 @@ export const server = pgTable("server", {
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
adminId: text("adminId")
userId: text("userId")
.notNull()
.references(() => admins.adminId, { onDelete: "cascade" }),
.references(() => users.id, { onDelete: "cascade" }),
serverStatus: serverStatus("serverStatus").notNull().default("active"),
command: text("command").notNull().default(""),
sshKeyId: text("sshKeyId").references(() => sshKeys.sshKeyId, {
@@ -100,9 +101,9 @@ export const server = pgTable("server", {
});
export const serverRelations = relations(server, ({ one, many }) => ({
admin: one(admins, {
fields: [server.adminId],
references: [admins.adminId],
user: one(users, {
fields: [server.userId],
references: [users.id],
}),
deployments: many(deployments),
sshKey: one(sshKeys, {

View File

@@ -1,13 +1,17 @@
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { auth } from "./auth";
import { users } from "./user";
// OLD TABLE
export const sessionTable = pgTable("session", {
id: text("id").primaryKey(),
expiresAt: timestamp("expires_at").notNull(),
token: text("token").notNull().unique(),
createdAt: timestamp("created_at").notNull(),
updatedAt: timestamp("updated_at").notNull(),
ipAddress: text("ip_address"),
userAgent: text("user_agent"),
userId: text("user_id")
.notNull()
.references(() => auth.id, { onDelete: "cascade" }),
expiresAt: timestamp("expires_at", {
withTimezone: true,
mode: "date",
}).notNull(),
.references(() => users.id),
impersonatedBy: text("impersonated_by"),
});

View File

@@ -7,6 +7,7 @@ import { admins } from "./admin";
import { applications } from "./application";
import { compose } from "./compose";
import { server } from "./server";
import { users } from "./user";
export const sshKeys = pgTable("ssh-key", {
sshKeyId: text("sshKeyId")
@@ -21,7 +22,7 @@ export const sshKeys = pgTable("ssh-key", {
.notNull()
.$defaultFn(() => new Date().toISOString()),
lastUsedAt: text("lastUsedAt"),
adminId: text("adminId").references(() => admins.adminId, {
userId: text("userId").references(() => users.id, {
onDelete: "cascade",
}),
});
@@ -30,9 +31,9 @@ export const sshKeysRelations = relations(sshKeys, ({ many, one }) => ({
applications: many(applications),
compose: many(compose),
servers: many(server),
admin: one(admins, {
fields: [sshKeys.adminId],
references: [admins.adminId],
user: one(users, {
fields: [sshKeys.userId],
references: [users.id],
}),
}));
@@ -48,7 +49,7 @@ export const apiCreateSshKey = createSchema
description: true,
privateKey: true,
publicKey: true,
adminId: true,
userId: true,
})
.merge(sshKeyCreate.pick({ privateKey: true }));

View File

@@ -1,10 +1,11 @@
import { relations, sql } from "drizzle-orm";
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { boolean, jsonb, pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { admins } from "./admin";
import { auth } from "./auth";
import { certificateType } from "./shared";
/**
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
* database instance for multiple projects.
@@ -12,12 +13,13 @@ import { auth } from "./auth";
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
*/
// OLD TABLE
export const users = pgTable("user", {
userId: text("userId")
id: text("id")
.notNull()
.primaryKey()
.$defaultFn(() => nanoid()),
name: text("name").notNull().default(""),
token: text("token").notNull(),
isRegistered: boolean("isRegistered").notNull().default(false),
expirationDate: timestamp("expirationDate", {
@@ -48,31 +50,102 @@ export const users = pgTable("user", {
.array()
.notNull()
.default(sql`ARRAY[]::text[]`),
adminId: text("adminId")
// authId: text("authId")
// .notNull()
// .references(() => auth.id, { onDelete: "cascade" }),
// Auth
email: text("email").notNull().unique(),
emailVerified: boolean("email_verified").notNull(),
image: text("image"),
role: text("role"),
banned: boolean("banned"),
banReason: text("ban_reason"),
banExpires: timestamp("ban_expires"),
updatedAt: timestamp("updated_at").notNull(),
// Admin
serverIp: text("serverIp"),
certificateType: certificateType("certificateType").notNull().default("none"),
host: text("host"),
letsEncryptEmail: text("letsEncryptEmail"),
sshPrivateKey: text("sshPrivateKey"),
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
enableLogRotation: boolean("enableLogRotation").notNull().default(false),
// Metrics
enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
metricsConfig: jsonb("metricsConfig")
.$type<{
server: {
type: "Dokploy" | "Remote";
refreshRate: number;
port: number;
token: string;
urlCallback: string;
retentionDays: number;
cronJob: string;
thresholds: {
cpu: number;
memory: number;
};
};
containers: {
refreshRate: number;
services: {
include: string[];
exclude: string[];
};
};
}>()
.notNull()
.references(() => admins.adminId, { onDelete: "cascade" }),
authId: text("authId")
.default({
server: {
type: "Dokploy",
refreshRate: 60,
port: 4500,
token: "",
retentionDays: 2,
cronJob: "",
urlCallback: "",
thresholds: {
cpu: 0,
memory: 0,
},
},
containers: {
refreshRate: 60,
services: {
include: [],
exclude: [],
},
},
}),
cleanupCacheApplications: boolean("cleanupCacheApplications")
.notNull()
.references(() => auth.id, { onDelete: "cascade" }),
.default(false),
cleanupCacheOnPreviews: boolean("cleanupCacheOnPreviews")
.notNull()
.default(false),
cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
.notNull()
.default(false),
});
export const usersRelations = relations(users, ({ one }) => ({
auth: one(auth, {
fields: [users.authId],
references: [auth.id],
}),
admin: one(admins, {
fields: [users.adminId],
references: [admins.adminId],
}),
// auth: one(auth, {
// fields: [users.authId],
// references: [auth.id],
// }),
// admin: one(admins, {
// fields: [users.adminId],
// references: [admins.adminId],
// }),
}));
const createSchema = createInsertSchema(users, {
userId: z.string().min(1),
authId: z.string().min(1),
id: z.string().min(1),
// authId: z.string().min(1),
token: z.string().min(1),
isRegistered: z.boolean().optional(),
adminId: z.string(),
// adminId: z.string(),
accessedProjects: z.array(z.string()).optional(),
accessedServices: z.array(z.string()).optional(),
canCreateProjects: z.boolean().optional(),
@@ -89,7 +162,7 @@ export const apiCreateUserInvitation = createSchema.pick({}).extend({
export const apiRemoveUser = createSchema
.pick({
authId: true,
// authId: true,
})
.required();
@@ -101,7 +174,7 @@ export const apiFindOneToken = createSchema
export const apiAssignPermissions = createSchema
.pick({
userId: true,
id: true,
canCreateProjects: true,
canCreateServices: true,
canDeleteProjects: true,
@@ -118,12 +191,12 @@ export const apiAssignPermissions = createSchema
export const apiFindOneUser = createSchema
.pick({
userId: true,
id: true,
})
.required();
export const apiFindOneUserByAuth = createSchema
.pick({
authId: true,
// authId: true,
})
.required();

View File

@@ -118,3 +118,5 @@ export * from "./monitoring/utils";
export * from "./db/validations/domain";
export * from "./db/validations/index";
export * from "./utils/gpu-setup";
export * from "./lib/auth";

View File

@@ -0,0 +1,14 @@
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { admin } from "better-auth/plugins";
import { db } from "../db";
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
}),
emailAndPassword: {
enabled: true,
},
plugins: [admin()],
});

View File

@@ -94,7 +94,9 @@ export const updateAdminById = async (
};
export const isAdminPresent = async () => {
const admin = await db.query.admins.findFirst();
const admin = await db.query.users.findFirst({
where: eq(users.role, "admin"),
});
if (!admin) {
return false;
}

View File

@@ -23,27 +23,27 @@ class LogRotationManager {
}
private async initialize(): Promise<void> {
const isActive = await this.getStateFromDB();
if (isActive) {
await this.activateStream();
}
// const isActive = await this.getStateFromDB();
// if (isActive) {
// await this.activateStream();
// }
}
private async getStateFromDB(): Promise<boolean> {
const setting = await db.query.admins.findFirst({});
return setting?.enableLogRotation ?? false;
}
// private async getStateFromDB(): Promise<boolean> {
// const setting = await db.query.admins.findFirst({});
// return setting?.enableLogRotation ?? false;
// }
private async setStateInDB(active: boolean): Promise<void> {
const admin = await db.query.admins.findFirst({});
// private async setStateInDB(active: boolean): Promise<void> {
// const admin = await db.query.admins.findFirst({});
if (!admin) {
return;
}
await updateAdmin(admin?.authId, {
enableLogRotation: active,
});
}
// if (!admin) {
// return;
// }
// await updateAdmin(admin?.authId, {
// enableLogRotation: active,
// });
// }
private async activateStream(): Promise<void> {
const { DYNAMIC_TRAEFIK_PATH } = paths();
@@ -76,26 +76,26 @@ class LogRotationManager {
}
public async activate(): Promise<boolean> {
const currentState = await this.getStateFromDB();
if (currentState) {
return true;
}
// const currentState = await this.getStateFromDB();
// if (currentState) {
// return true;
// }
await this.setStateInDB(true);
await this.activateStream();
// await this.setStateInDB(true);
// await this.activateStream();
return true;
}
public async deactivate(): Promise<boolean> {
console.log("Deactivating log rotation...");
const currentState = await this.getStateFromDB();
if (!currentState) {
console.log("Log rotation is already inactive in DB");
return true;
}
// const currentState = await this.getStateFromDB();
// if (!currentState) {
// console.log("Log rotation is already inactive in DB");
// return true;
// }
await this.setStateInDB(false);
await this.deactivateStream();
// await this.setStateInDB(false);
// await this.deactivateStream();
console.log("Log rotation deactivated successfully");
return true;
}
@@ -115,8 +115,9 @@ class LogRotationManager {
}
}
public async getStatus(): Promise<boolean> {
const dbState = await this.getStateFromDB();
return dbState;
// const dbState = await this.getStateFromDB();
// return dbState;
return false;
}
}
export const logRotationManager = LogRotationManager.getInstance();