mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
chore: clean up unused variables and improve error handling across codebase
This commit focuses on removing unused variables, adding placeholder error handling, and generally tidying up various files across the Dokploy application. Changes include: - Removing unused imports and variables - Adding placeholder error handling in catch blocks - Cleaning up commented-out code - Removing deprecated utility files - Improving type safety and code consistency
This commit is contained in:
parent
1a415b96c9
commit
8ab6d6b282
@ -130,7 +130,7 @@ const createStringToJSONSchema = (schema: z.ZodTypeAny) => {
|
||||
}
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch (e) {
|
||||
} catch (_e) {
|
||||
ctx.addIssue({ code: "custom", message: "Invalid JSON format" });
|
||||
return z.NEVER;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ export const UpdateVolume = ({
|
||||
serviceType,
|
||||
}: Props) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const utils = api.useUtils();
|
||||
const _utils = api.useUtils();
|
||||
const { data } = api.mounts.one.useQuery(
|
||||
{
|
||||
mountId,
|
||||
|
@ -84,7 +84,6 @@ export const SaveBitbucketProvider = ({ applicationId }: Props) => {
|
||||
data: repositories,
|
||||
isLoading: isLoadingRepositories,
|
||||
error,
|
||||
isError,
|
||||
} = api.bitbucket.getBitbucketRepositories.useQuery(
|
||||
{
|
||||
bitbucketId,
|
||||
|
@ -27,8 +27,7 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
||||
const { mutateAsync: stop, isLoading: isStopping } =
|
||||
api.application.stop.useMutation();
|
||||
|
||||
const { mutateAsync: deploy, isLoading: isDeploying } =
|
||||
api.application.deploy.useMutation();
|
||||
const { mutateAsync: deploy } = api.application.deploy.useMutation();
|
||||
|
||||
const { mutateAsync: reload, isLoading: isReloading } =
|
||||
api.application.reload.useMutation();
|
||||
|
@ -279,7 +279,7 @@ export const ShowPreviewSettings = ({ applicationId }: Props) => {
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="env"
|
||||
render={({ field }) => (
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Secrets
|
||||
|
@ -60,7 +60,7 @@ export const DeleteService = ({ id, type }: Props) => {
|
||||
compose: () =>
|
||||
api.compose.one.useQuery({ composeId: id }, { enabled: !!id }),
|
||||
};
|
||||
const { data, refetch } = queryMap[type]
|
||||
const { data } = queryMap[type]
|
||||
? queryMap[type]()
|
||||
: api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id });
|
||||
|
||||
|
@ -118,7 +118,7 @@ export const ShowDomainsCompose = ({ composeId }: Props) => {
|
||||
await deleteDomain({
|
||||
domainId: item.domainId,
|
||||
})
|
||||
.then((data) => {
|
||||
.then((_data) => {
|
||||
refetch();
|
||||
toast.success("Domain deleted successfully");
|
||||
})
|
||||
|
@ -35,8 +35,7 @@ export const ComposeFileEditor = ({ composeId }: Props) => {
|
||||
{ enabled: !!composeId },
|
||||
);
|
||||
|
||||
const { mutateAsync, isLoading, error, isError } =
|
||||
api.compose.update.useMutation();
|
||||
const { mutateAsync, isLoading } = api.compose.update.useMutation();
|
||||
|
||||
const form = useForm<AddComposeFile>({
|
||||
defaultValues: {
|
||||
@ -76,7 +75,7 @@ export const ComposeFileEditor = ({ composeId }: Props) => {
|
||||
composeId,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch((_e) => {
|
||||
toast.error("Error updating the Compose config");
|
||||
});
|
||||
};
|
||||
|
@ -84,7 +84,6 @@ export const SaveBitbucketProviderCompose = ({ composeId }: Props) => {
|
||||
data: repositories,
|
||||
isLoading: isLoadingRepositories,
|
||||
error,
|
||||
isError,
|
||||
} = api.bitbucket.getBitbucketRepositories.useQuery(
|
||||
{
|
||||
bitbucketId,
|
||||
|
@ -70,7 +70,7 @@ export const IsolatedDeployment = ({ composeId }: Props) => {
|
||||
composeId,
|
||||
isolatedDeployment: formData?.isolatedDeployment || false,
|
||||
})
|
||||
.then(async (data) => {
|
||||
.then(async (_data) => {
|
||||
randomizeCompose();
|
||||
refetch();
|
||||
toast.success("Compose updated");
|
||||
|
@ -39,7 +39,7 @@ type Schema = z.infer<typeof schema>;
|
||||
export const RandomizeCompose = ({ composeId }: Props) => {
|
||||
const utils = api.useUtils();
|
||||
const [compose, setCompose] = useState<string>("");
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [_isOpen, _setIsOpen] = useState(false);
|
||||
const { mutateAsync, error, isError } =
|
||||
api.compose.randomizeCompose.useMutation();
|
||||
|
||||
@ -76,7 +76,7 @@ export const RandomizeCompose = ({ composeId }: Props) => {
|
||||
suffix: formData?.suffix || "",
|
||||
randomize: formData?.randomize || false,
|
||||
})
|
||||
.then(async (data) => {
|
||||
.then(async (_data) => {
|
||||
randomizeCompose();
|
||||
refetch();
|
||||
toast.success("Compose updated");
|
||||
|
@ -40,7 +40,7 @@ export const ShowConvertedCompose = ({ composeId }: Props) => {
|
||||
.then(() => {
|
||||
refetch();
|
||||
})
|
||||
.catch((err) => {});
|
||||
.catch((_err) => {});
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
|
@ -29,14 +29,6 @@ interface Props {
|
||||
data: ContainerMetric[];
|
||||
}
|
||||
|
||||
interface FormattedMetric {
|
||||
timestamp: string;
|
||||
read: number;
|
||||
write: number;
|
||||
readUnit: string;
|
||||
writeUnit: string;
|
||||
}
|
||||
|
||||
const chartConfig = {
|
||||
read: {
|
||||
label: "Read",
|
||||
|
@ -20,7 +20,7 @@ interface Props {
|
||||
organizationId?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
export function AddOrganization({ organizationId, children }: Props) {
|
||||
export function AddOrganization({ organizationId }: Props) {
|
||||
const utils = api.useUtils();
|
||||
const { data: organization } = api.organization.one.useQuery(
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
|
||||
mongo: () => api.mongo.update.useMutation(),
|
||||
};
|
||||
|
||||
const { mutateAsync, isLoading } = mutationMap[type]
|
||||
const { mutateAsync } = mutationMap[type]
|
||||
? mutationMap[type]()
|
||||
: api.mongo.update.useMutation();
|
||||
|
||||
|
@ -103,7 +103,7 @@ export const AddApplication = ({ projectId, projectName }: Props) => {
|
||||
projectId,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch((_e) => {
|
||||
toast.error("Error creating the service");
|
||||
});
|
||||
};
|
||||
|
@ -434,14 +434,14 @@ export const AddTemplate = ({ projectId }: Props) => {
|
||||
});
|
||||
toast.promise(promise, {
|
||||
loading: "Setting up...",
|
||||
success: (data) => {
|
||||
success: (_data) => {
|
||||
utils.project.one.invalidate({
|
||||
projectId,
|
||||
});
|
||||
setOpen(false);
|
||||
return `${template.name} template created successfully`;
|
||||
},
|
||||
error: (err) => {
|
||||
error: (_err) => {
|
||||
return `An error ocurred deploying ${template.name} template`;
|
||||
},
|
||||
});
|
||||
|
@ -79,7 +79,7 @@ export const ShowExternalRedisCredentials = ({ redisId }: Props) => {
|
||||
|
||||
useEffect(() => {
|
||||
const buildConnectionUrl = () => {
|
||||
const hostname = window.location.hostname;
|
||||
const _hostname = window.location.hostname;
|
||||
const port = form.watch("externalPort") || data?.externalPort;
|
||||
|
||||
return `redis://default:${data?.databasePassword}@${getIp}:${port}`;
|
||||
|
@ -24,7 +24,7 @@ export const getStatusColor = (status: number) => {
|
||||
export const columns: ColumnDef<LogEntry>[] = [
|
||||
{
|
||||
accessorKey: "level",
|
||||
header: ({ column }) => {
|
||||
header: () => {
|
||||
return <Button variant="ghost">Level</Button>;
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
|
@ -92,7 +92,7 @@ export const RequestsTable = () => {
|
||||
pageSize: 10,
|
||||
});
|
||||
|
||||
const { data: statsLogs, isLoading } = api.settings.readStatsLogs.useQuery(
|
||||
const { data: statsLogs } = api.settings.readStatsLogs.useQuery(
|
||||
{
|
||||
sort: sorting[0],
|
||||
page: pagination,
|
||||
@ -300,7 +300,7 @@ export const RequestsTable = () => {
|
||||
</div>
|
||||
<Sheet
|
||||
open={!!selectedRow}
|
||||
onOpenChange={(open) => setSelectedRow(undefined)}
|
||||
onOpenChange={(_open) => setSelectedRow(undefined)}
|
||||
>
|
||||
<SheetContent className="sm:max-w-[740px] flex flex-col">
|
||||
<SheetHeader>
|
||||
|
@ -22,14 +22,11 @@ import {
|
||||
extractServices,
|
||||
} from "@/pages/dashboard/project/[projectId]";
|
||||
import { api } from "@/utils/api";
|
||||
import type { findProjectById } from "@dokploy/server/services/project";
|
||||
import { BookIcon, CircuitBoard, GlobeIcon } from "lucide-react";
|
||||
import { useRouter } from "next/router";
|
||||
import React from "react";
|
||||
import { StatusTooltip } from "../shared/status-tooltip";
|
||||
|
||||
type Project = Awaited<ReturnType<typeof findProjectById>>;
|
||||
|
||||
export const SearchCommand = () => {
|
||||
const router = useRouter();
|
||||
const [open, setOpen] = React.useState(false);
|
||||
@ -38,7 +35,7 @@ export const SearchCommand = () => {
|
||||
const { data } = api.project.all.useQuery(undefined, {
|
||||
enabled: !!session,
|
||||
});
|
||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
|
@ -38,7 +38,7 @@ export const calculatePrice = (count: number, isAnnual = false) => {
|
||||
return count * 3.5;
|
||||
};
|
||||
export const ShowBilling = () => {
|
||||
const { data: servers } = api.server.all.useQuery(undefined);
|
||||
const { data: servers } = api.server.count.useQuery();
|
||||
const { data: admin } = api.user.get.useQuery();
|
||||
const { data, isLoading } = api.stripe.getProducts.useQuery();
|
||||
const { mutateAsync: createCheckoutSession } =
|
||||
@ -71,7 +71,7 @@ export const ShowBilling = () => {
|
||||
});
|
||||
|
||||
const maxServers = admin?.user.serversQuantity ?? 1;
|
||||
const percentage = ((servers?.length ?? 0) / maxServers) * 100;
|
||||
const percentage = ((servers ?? 0) / maxServers) * 100;
|
||||
const safePercentage = Math.min(percentage, 100);
|
||||
|
||||
return (
|
||||
@ -102,13 +102,13 @@ export const ShowBilling = () => {
|
||||
<div className="space-y-2 flex flex-col">
|
||||
<h3 className="text-lg font-medium">Servers Plan</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
You have {servers?.length} server on your plan of{" "}
|
||||
You have {servers} server on your plan of{" "}
|
||||
{admin?.user.serversQuantity} servers
|
||||
</p>
|
||||
<div>
|
||||
<Progress value={safePercentage} className="max-w-lg" />
|
||||
</div>
|
||||
{admin && admin.user.serversQuantity! <= servers?.length! && (
|
||||
{admin && admin.user.serversQuantity! <= (servers ?? 0) && (
|
||||
<div className="flex flex-row gap-4 p-2 bg-yellow-50 dark:bg-yellow-950 rounded-lg items-center">
|
||||
<AlertTriangle className="text-yellow-600 dark:text-yellow-400" />
|
||||
<span className="text-sm text-yellow-600 dark:text-yellow-400">
|
||||
|
@ -41,8 +41,7 @@ export const ShowNodes = () => {
|
||||
const { data, isLoading, refetch } = api.cluster.getNodes.useQuery();
|
||||
const { data: registry } = api.registry.all.useQuery();
|
||||
|
||||
const { mutateAsync: deleteNode, isLoading: isRemoving } =
|
||||
api.cluster.removeWorker.useMutation();
|
||||
const { mutateAsync: deleteNode } = api.cluster.removeWorker.useMutation();
|
||||
|
||||
const haveAtLeastOneRegistry = !!(registry && registry?.length > 0);
|
||||
return (
|
||||
|
@ -131,7 +131,7 @@ export const HandleRegistry = ({ registryId }: Props) => {
|
||||
serverId: data.serverId,
|
||||
registryId: registryId || "",
|
||||
})
|
||||
.then(async (data) => {
|
||||
.then(async (_data) => {
|
||||
await utils.registry.all.invalidate();
|
||||
toast.success(registryId ? "Registry updated" : "Registry added");
|
||||
setIsOpen(false);
|
||||
|
@ -47,10 +47,10 @@ type Schema = z.infer<typeof Schema>;
|
||||
export const AddBitbucketProvider = () => {
|
||||
const utils = api.useUtils();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const url = useUrl();
|
||||
const _url = useUrl();
|
||||
const { mutateAsync, error, isError } = api.bitbucket.create.useMutation();
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const router = useRouter();
|
||||
const _router = useRouter();
|
||||
const form = useForm<Schema>({
|
||||
defaultValues: {
|
||||
username: "",
|
||||
|
@ -102,7 +102,7 @@ export const ShowGitProviders = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 rounded-lg ">
|
||||
{data?.map((gitProvider, index) => {
|
||||
{data?.map((gitProvider, _index) => {
|
||||
const isGithub = gitProvider.providerType === "github";
|
||||
const isGitlab = gitProvider.providerType === "gitlab";
|
||||
const isBitbucket =
|
||||
|
@ -136,7 +136,7 @@ export const HandleNotifications = ({ notificationId }: Props) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
const { data: notification, refetch } = api.notification.one.useQuery(
|
||||
const { data: notification } = api.notification.one.useQuery(
|
||||
{
|
||||
notificationId: notificationId || "",
|
||||
},
|
||||
@ -1038,7 +1038,7 @@ export const HandleNotifications = ({ notificationId }: Props) => {
|
||||
});
|
||||
}
|
||||
toast.success("Connection Success");
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
toast.error("Error testing the provider");
|
||||
}
|
||||
}}
|
||||
|
@ -56,7 +56,7 @@ export const ShowNotifications = () => {
|
||||
) : (
|
||||
<div className="flex flex-col gap-4 min-h-[25vh]">
|
||||
<div className="flex flex-col gap-4 rounded-lg ">
|
||||
{data?.map((notification, index) => (
|
||||
{data?.map((notification, _index) => (
|
||||
<div
|
||||
key={notification.notificationId}
|
||||
className="flex items-center justify-between bg-sidebar p-1 w-full rounded-lg"
|
||||
|
@ -63,7 +63,7 @@ export const Disable2FA = () => {
|
||||
toast.success("2FA disabled successfully");
|
||||
utils.auth.get.invalidate();
|
||||
setIsOpen(false);
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
form.setError("password", {
|
||||
message: "Connection error. Please try again.",
|
||||
});
|
||||
|
@ -47,20 +47,8 @@ const PinSchema = z.object({
|
||||
type PasswordForm = z.infer<typeof PasswordSchema>;
|
||||
type PinForm = z.infer<typeof PinSchema>;
|
||||
|
||||
type TwoFactorEnableResponse = {
|
||||
totpURI: string;
|
||||
backupCodes: string[];
|
||||
};
|
||||
|
||||
type TwoFactorSetupData = {
|
||||
qrCodeUrl: string;
|
||||
secret: string;
|
||||
totpURI: string;
|
||||
};
|
||||
|
||||
export const Enable2FA = () => {
|
||||
const utils = api.useUtils();
|
||||
const { data: session } = authClient.useSession();
|
||||
const [data, setData] = useState<TwoFactorSetupData | null>(null);
|
||||
const [backupCodes, setBackupCodes] = useState<string[]>([]);
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
|
@ -54,9 +54,7 @@ const randomImages = [
|
||||
];
|
||||
|
||||
export const ProfileForm = () => {
|
||||
const utils = api.useUtils();
|
||||
const { mutateAsync: disable2FA, isLoading: isDisabling } =
|
||||
api.auth.disable2FA.useMutation();
|
||||
const _utils = api.useUtils();
|
||||
const { data, refetch, isLoading } = api.user.get.useQuery();
|
||||
const {
|
||||
mutateAsync,
|
||||
|
@ -26,7 +26,7 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
||||
isLoading: cleanDockerBuilderIsLoading,
|
||||
} = api.settings.cleanDockerBuilder.useMutation();
|
||||
|
||||
const { mutateAsync: cleanMonitoring, isLoading: cleanMonitoringIsLoading } =
|
||||
const { mutateAsync: cleanMonitoring } =
|
||||
api.settings.cleanMonitoring.useMutation();
|
||||
const {
|
||||
mutateAsync: cleanUnusedImages,
|
||||
|
@ -36,7 +36,7 @@ export const ToggleDockerCleanup = ({ serverId }: Props) => {
|
||||
await refetch();
|
||||
}
|
||||
toast.success("Docker Cleanup updated");
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error("Docker Cleanup Error");
|
||||
}
|
||||
};
|
||||
|
@ -82,7 +82,7 @@ export const EditScript = ({ serverId }: Props) => {
|
||||
command: formData.command || "",
|
||||
serverId,
|
||||
})
|
||||
.then((data) => {
|
||||
.then((_data) => {
|
||||
toast.success("Script modified successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -56,7 +56,7 @@ export function GPUSupport({ serverId }: GPUSupportProps) {
|
||||
try {
|
||||
await utils.settings.checkGPUStatus.invalidate({ serverId });
|
||||
await refetch();
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error("Failed to refresh GPU status");
|
||||
} finally {
|
||||
setIsRefreshing(false);
|
||||
@ -74,7 +74,7 @@ export function GPUSupport({ serverId }: GPUSupportProps) {
|
||||
|
||||
try {
|
||||
await setupGPU.mutateAsync({ serverId });
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
// Error handling is done in mutation's onError
|
||||
}
|
||||
};
|
||||
|
@ -118,7 +118,7 @@ export const HandleServers = ({ serverId }: Props) => {
|
||||
sshKeyId: data.sshKeyId || "",
|
||||
serverId: serverId || "",
|
||||
})
|
||||
.then(async (data) => {
|
||||
.then(async (_data) => {
|
||||
await utils.server.all.invalidate();
|
||||
refetchServer();
|
||||
toast.success(serverId ? "Server Updated" : "Server Created");
|
||||
|
@ -25,7 +25,7 @@ export const SecurityAudit = ({ serverId }: Props) => {
|
||||
enabled: !!serverId,
|
||||
},
|
||||
);
|
||||
const utils = api.useUtils();
|
||||
const _utils = api.useUtils();
|
||||
return (
|
||||
<CardContent className="p-0">
|
||||
<div className="flex flex-col gap-4">
|
||||
|
@ -80,7 +80,7 @@ const Schema = z.object({
|
||||
type Schema = z.infer<typeof Schema>;
|
||||
|
||||
export const SetupMonitoring = ({ serverId }: Props) => {
|
||||
const { data, isLoading } = serverId
|
||||
const { data } = serverId
|
||||
? api.server.one.useQuery(
|
||||
{
|
||||
serverId: serverId || "",
|
||||
|
@ -25,7 +25,7 @@ export const ValidateServer = ({ serverId }: Props) => {
|
||||
enabled: !!serverId,
|
||||
},
|
||||
);
|
||||
const utils = api.useUtils();
|
||||
const _utils = api.useUtils();
|
||||
return (
|
||||
<CardContent className="p-0">
|
||||
<div className="flex flex-col gap-4">
|
||||
|
@ -52,10 +52,10 @@ interface Props {
|
||||
|
||||
export const CreateServer = ({ stepper }: Props) => {
|
||||
const { data: sshKeys } = api.sshKey.all.useQuery();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isOpen, _setIsOpen] = useState(false);
|
||||
const { data: canCreateMoreServers, refetch } =
|
||||
api.stripe.canCreateMoreServers.useQuery();
|
||||
const { mutateAsync, error, isError } = api.server.create.useMutation();
|
||||
const { mutateAsync } = api.server.create.useMutation();
|
||||
const cloudSSHKey = sshKeys?.find(
|
||||
(sshKey) => sshKey.name === "dokploy-cloud-ssh-key",
|
||||
);
|
||||
@ -96,7 +96,7 @@ export const CreateServer = ({ stepper }: Props) => {
|
||||
username: data.username || "root",
|
||||
sshKeyId: data.sshKeyId || "",
|
||||
})
|
||||
.then(async (data) => {
|
||||
.then(async (_data) => {
|
||||
toast.success("Server Created");
|
||||
stepper.next();
|
||||
})
|
||||
|
@ -37,15 +37,6 @@ export const Verify = () => {
|
||||
);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
|
||||
const { data: server } = api.server.one.useQuery(
|
||||
{
|
||||
serverId,
|
||||
},
|
||||
{
|
||||
enabled: !!serverId,
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<CardContent className="p-0">
|
||||
<div className="flex flex-col gap-4">
|
||||
|
@ -143,7 +143,7 @@ export const ShowInvitations = () => {
|
||||
{invitation.status === "pending" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={(e) => {
|
||||
onSelect={(_e) => {
|
||||
copy(
|
||||
`${origin}/invitation?token=${invitation.id}`,
|
||||
);
|
||||
@ -159,7 +159,7 @@ export const ShowInvitations = () => {
|
||||
{invitation.status === "pending" && (
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onSelect={async (e) => {
|
||||
onSelect={async (_e) => {
|
||||
const result =
|
||||
await authClient.organization.cancelInvitation(
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ import { AddUserPermissions } from "./add-permissions";
|
||||
export const ShowUsers = () => {
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
const { data, isLoading, refetch } = api.user.all.useQuery();
|
||||
const { mutateAsync, isLoading: isRemoving } = api.user.remove.useMutation();
|
||||
const { mutateAsync } = api.user.remove.useMutation();
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
|
@ -14,10 +14,7 @@ import { ShowTraefikActions } from "./servers/actions/show-traefik-actions";
|
||||
import { ToggleDockerCleanup } from "./servers/actions/toggle-docker-cleanup";
|
||||
import { UpdateServer } from "./web-server/update-server";
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
export const WebServer = ({ className }: Props) => {
|
||||
export const WebServer = () => {
|
||||
const { t } = useTranslation("settings");
|
||||
const { data } = api.user.get.useQuery();
|
||||
|
||||
|
@ -99,7 +99,7 @@ export const ManageTraefikPorts = ({ children, serverId }: Props) => {
|
||||
});
|
||||
toast.success(t("settings.server.webServer.traefik.portsUpdated"));
|
||||
setOpen(false);
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error(t("settings.server.webServer.traefik.portsUpdateError"));
|
||||
}
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ interface Props {
|
||||
serverId?: string;
|
||||
}
|
||||
|
||||
export const UpdateServerIp = ({ children, serverId }: Props) => {
|
||||
export const UpdateServerIp = ({ children }: Props) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const { data } = api.user.get.useQuery();
|
||||
|
@ -214,7 +214,7 @@ export const columns: ColumnDef<ApplicationList>[] = [
|
||||
{
|
||||
accessorKey: "Logs",
|
||||
accessorFn: (row) => row.Error,
|
||||
header: ({ column }) => {
|
||||
header: () => {
|
||||
return <span>Logs</span>;
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
|
@ -48,7 +48,7 @@ export function DataTable<TData, TValue>({
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
const [pagination, setPagination] = React.useState({
|
||||
const [_pagination, _setPagination] = React.useState({
|
||||
pageIndex: 0, //initial page index
|
||||
pageSize: 8, //default page size
|
||||
});
|
||||
|
@ -17,7 +17,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export const ShowNodeConfig = ({ nodeId, serverId }: Props) => {
|
||||
const { data, isLoading } = api.swarm.getNodeInfo.useQuery({
|
||||
const { data } = api.swarm.getNodeInfo.useQuery({
|
||||
nodeId,
|
||||
serverId,
|
||||
});
|
||||
|
@ -157,7 +157,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/monitoring",
|
||||
icon: BarChartHorizontalBigIcon,
|
||||
// Only enabled in non-cloud environments
|
||||
isEnabled: ({ auth, isCloud }) => !isCloud,
|
||||
isEnabled: ({ isCloud }) => !isCloud,
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@ -277,7 +277,7 @@ const MENU: Menu = {
|
||||
url: "/dashboard/settings/servers",
|
||||
icon: Server,
|
||||
// Only enabled for admins
|
||||
isEnabled: ({ auth, isCloud }) => !!(auth?.role === "owner"),
|
||||
isEnabled: ({ auth }) => !!(auth?.role === "owner"),
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@ -490,8 +490,9 @@ function SidebarLogo() {
|
||||
const { state } = useSidebar();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
const { data: user } = api.user.get.useQuery();
|
||||
const { data: dokployVersion } = api.settings.getDokployVersion.useQuery();
|
||||
// const { data: dokployVersion } = api.settings.getDokployVersion.useQuery();
|
||||
const { data: session } = authClient.useSession();
|
||||
|
||||
const {
|
||||
data: organizations,
|
||||
refetch,
|
||||
@ -501,12 +502,12 @@ function SidebarLogo() {
|
||||
api.organization.delete.useMutation();
|
||||
const { isMobile } = useSidebar();
|
||||
const { data: activeOrganization } = authClient.useActiveOrganization();
|
||||
const utils = api.useUtils();
|
||||
const _utils = api.useUtils();
|
||||
|
||||
const { data: invitations, refetch: refetchInvitations } =
|
||||
api.user.getInvitations.useQuery();
|
||||
|
||||
const [activeTeam, setActiveTeam] = useState<
|
||||
const [_activeTeam, setActiveTeam] = useState<
|
||||
typeof activeOrganization | null
|
||||
>(null);
|
||||
|
||||
@ -543,7 +544,7 @@ function SidebarLogo() {
|
||||
</div>
|
||||
<div className="flex flex-col items-start">
|
||||
<p className="text-sm font-medium leading-none">
|
||||
{activeOrganization?.name}
|
||||
{activeOrganization?.name ?? "Select Organization"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -551,7 +552,7 @@ function SidebarLogo() {
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className="w-[--radix-dropdown-menu-trigger-width] min-w-64 rounded-lg"
|
||||
className=" rounded-lg"
|
||||
align="start"
|
||||
side={isMobile ? "bottom" : "right"}
|
||||
sideOffset={4}
|
||||
@ -570,6 +571,7 @@ function SidebarLogo() {
|
||||
}}
|
||||
className="w-full gap-2 p-2"
|
||||
>
|
||||
<div className="flex flex-col gap-4">{org.name}</div>
|
||||
<div className="flex size-6 items-center justify-center rounded-sm border">
|
||||
<Logo
|
||||
className={cn(
|
||||
@ -578,9 +580,8 @@ function SidebarLogo() {
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{org.name}
|
||||
</DropdownMenuItem>
|
||||
{(org.ownerId === session?.user?.id || isCloud) && (
|
||||
{org.ownerId === session?.user?.id && (
|
||||
<div className="flex items-center gap-2">
|
||||
<AddOrganization organizationId={org.id} />
|
||||
<DialogAction
|
||||
@ -618,7 +619,7 @@ function SidebarLogo() {
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{!isCloud && user?.role === "owner" && (
|
||||
{(user?.role === "owner" || isCloud) && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<AddOrganization />
|
||||
@ -721,11 +722,11 @@ export default function Page({ children }: Props) {
|
||||
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const currentPath = router.pathname;
|
||||
const _currentPath = router.pathname;
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
|
||||
const includesProjects = pathname?.includes("/dashboard/project");
|
||||
const { data: isCloud, isLoading } = api.settings.isCloud.useQuery();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
const {
|
||||
home: filteredHome,
|
||||
|
@ -11,7 +11,7 @@ export const UpdateServerButton = () => {
|
||||
latestVersion: null,
|
||||
updateAvailable: false,
|
||||
});
|
||||
const router = useRouter();
|
||||
const _router = useRouter();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
const { mutateAsync: getUpdateData } =
|
||||
api.settings.getUpdateData.useMutation();
|
||||
|
@ -24,7 +24,7 @@ import { useRouter } from "next/router";
|
||||
import { ModeToggle } from "../ui/modeToggle";
|
||||
import { SidebarMenuButton } from "../ui/sidebar";
|
||||
|
||||
const AUTO_CHECK_UPDATES_INTERVAL_MINUTES = 7;
|
||||
const _AUTO_CHECK_UPDATES_INTERVAL_MINUTES = 7;
|
||||
|
||||
export const UserNav = () => {
|
||||
const router = useRouter();
|
||||
|
@ -26,7 +26,7 @@ export const BreadcrumbSidebar = ({ list }: Props) => {
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
{list.map((item, index) => (
|
||||
{list.map((item, _index) => (
|
||||
<Fragment key={item.name}>
|
||||
<BreadcrumbItem className="block">
|
||||
<BreadcrumbLink href={item.href} asChild={!!item.href}>
|
||||
|
@ -43,7 +43,7 @@ export const DrawerLogs = ({ isOpen, onClose, filteredLogs }: Props) => {
|
||||
return (
|
||||
<Sheet
|
||||
open={!!isOpen}
|
||||
onOpenChange={(open) => {
|
||||
onOpenChange={(_open) => {
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
|
@ -85,7 +85,7 @@ const Tree = React.forwardRef<HTMLDivElement, TreeProps>(
|
||||
return ids;
|
||||
}, [data, initialSlelectedItemId]);
|
||||
|
||||
const { ref: refRoot, width, height } = useResizeObserver();
|
||||
const { ref: refRoot } = useResizeObserver();
|
||||
|
||||
return (
|
||||
<div ref={refRoot} className={cn("overflow-y-auto", className)}>
|
||||
|
@ -136,7 +136,7 @@ await db
|
||||
},
|
||||
});
|
||||
for (const project of projects) {
|
||||
const user = await db.update(schema.projects).set({
|
||||
const _user = await db.update(schema.projects).set({
|
||||
organizationId: project.user.organizations[0]?.id || "",
|
||||
});
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ export default function Custom404({ statusCode, error }: Props) {
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
Error.getInitialProps = ({ res, err, ...rest }: NextPageContext) => {
|
||||
Error.getInitialProps = ({ res, err }: NextPageContext) => {
|
||||
const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
|
||||
return { statusCode, error: err };
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
_req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
return res.status(200).json({ ok: true });
|
||||
|
@ -16,8 +16,7 @@ export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
const { code, state, installation_id, setup_action }: Query =
|
||||
req.query as Query;
|
||||
const { code, state, installation_id }: Query = req.query as Query;
|
||||
|
||||
if (!code) {
|
||||
return res.status(400).json({ error: "Missing code parameter" });
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { buffer } from "node:stream/consumers";
|
||||
import { db } from "@/server/db";
|
||||
import { server, users_temp } from "@/server/db/schema";
|
||||
import { findUserById } from "@dokploy/server";
|
||||
import { organization, server, users_temp } from "@/server/db/schema";
|
||||
import { findUserById, type Server } from "@dokploy/server";
|
||||
import { asc, eq } from "drizzle-orm";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import Stripe from "stripe";
|
||||
@ -172,11 +172,11 @@ export default async function handler(
|
||||
}
|
||||
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
serversQuantity: suscription?.items?.data?.[0]?.quantity ?? 0,
|
||||
})
|
||||
.where(eq(admins.stripeCustomerId, suscription.customer as string));
|
||||
.where(eq(users_temp.stripeCustomerId, suscription.customer as string));
|
||||
|
||||
const admin = await findUserByStripeCustomerId(
|
||||
suscription.customer as string,
|
||||
@ -205,11 +205,13 @@ export default async function handler(
|
||||
return res.status(400).send("Webhook Error: Admin not found");
|
||||
}
|
||||
await db
|
||||
.update(admins)
|
||||
.update(users_temp)
|
||||
.set({
|
||||
serversQuantity: 0,
|
||||
})
|
||||
.where(eq(admins.stripeCustomerId, newInvoice.customer as string));
|
||||
.where(
|
||||
eq(users_temp.stripeCustomerId, newInvoice.customer as string),
|
||||
);
|
||||
|
||||
await disableServers(admin.id);
|
||||
}
|
||||
@ -245,12 +247,18 @@ export default async function handler(
|
||||
}
|
||||
|
||||
const disableServers = async (userId: string) => {
|
||||
await db
|
||||
.update(server)
|
||||
.set({
|
||||
serverStatus: "inactive",
|
||||
})
|
||||
.where(eq(server.userId, userId));
|
||||
const organizations = await db.query.organization.findMany({
|
||||
where: eq(organization.ownerId, userId),
|
||||
});
|
||||
|
||||
for (const org of organizations) {
|
||||
await db
|
||||
.update(server)
|
||||
.set({
|
||||
serverStatus: "inactive",
|
||||
})
|
||||
.where(eq(server.organizationId, org.id));
|
||||
}
|
||||
};
|
||||
|
||||
const findUserByStripeCustomerId = async (stripeCustomerId: string) => {
|
||||
@ -275,11 +283,19 @@ const deactivateServer = async (serverId: string) => {
|
||||
};
|
||||
|
||||
export const findServersByUserIdSorted = async (userId: string) => {
|
||||
const servers = await db.query.server.findMany({
|
||||
where: eq(server.userId, userId),
|
||||
orderBy: asc(server.createdAt),
|
||||
const organizations = await db.query.organization.findMany({
|
||||
where: eq(organization.ownerId, userId),
|
||||
});
|
||||
|
||||
const servers: Server[] = [];
|
||||
for (const org of organizations) {
|
||||
const serversByOrg = await db.query.server.findMany({
|
||||
where: eq(server.organizationId, org.id),
|
||||
orderBy: asc(server.createdAt),
|
||||
});
|
||||
servers.push(...serversByOrg);
|
||||
}
|
||||
|
||||
return servers;
|
||||
};
|
||||
export const updateServersBasedOnQuantity = async (
|
||||
|
@ -72,7 +72,7 @@ export async function getServerSideProps(
|
||||
trpcState: helpers.dehydrate(),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
|
@ -15,8 +15,7 @@ const BASE_URL = "http://localhost:3001/metrics";
|
||||
const DEFAULT_TOKEN = "metrics";
|
||||
|
||||
const Dashboard = () => {
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
const [toggleMonitoring, setToggleMonitoring] = useLocalStorage(
|
||||
const [toggleMonitoring, _setToggleMonitoring] = useLocalStorage(
|
||||
"monitoring-enabled",
|
||||
false,
|
||||
);
|
||||
|
@ -261,7 +261,7 @@ const Project = (
|
||||
try {
|
||||
await composeActions.start.mutateAsync({ composeId: serviceId });
|
||||
success++;
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error(`Error starting service ${serviceId}`);
|
||||
}
|
||||
}
|
||||
@ -281,7 +281,7 @@ const Project = (
|
||||
try {
|
||||
await composeActions.stop.mutateAsync({ composeId: serviceId });
|
||||
success++;
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error(`Error stopping service ${serviceId}`);
|
||||
}
|
||||
}
|
||||
@ -685,7 +685,7 @@ export async function getServerSideProps(
|
||||
projectId: params?.projectId,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -65,7 +65,7 @@ type TabState =
|
||||
const Service = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
const { applicationId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
@ -86,7 +86,6 @@ const Service = (
|
||||
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
|
||||
return (
|
||||
<div className="pb-10">
|
||||
@ -399,7 +398,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -59,7 +59,7 @@ type TabState =
|
||||
const Service = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
const { composeId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
@ -79,7 +79,6 @@ const Service = (
|
||||
);
|
||||
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
return (
|
||||
@ -393,7 +392,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -52,7 +52,7 @@ type TabState = "projects" | "monitoring" | "settings" | "backups" | "advanced";
|
||||
const Mariadb = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
|
||||
const { mariadbId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
@ -60,7 +60,6 @@ const Mariadb = (
|
||||
const [tab, setSab] = useState<TabState>(activeTab);
|
||||
const { data } = api.mariadb.one.useQuery({ mariadbId });
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
@ -342,7 +341,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -52,7 +52,7 @@ type TabState = "projects" | "monitoring" | "settings" | "backups" | "advanced";
|
||||
const Mongo = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
const { mongoId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
@ -60,7 +60,6 @@ const Mongo = (
|
||||
const { data } = api.mongo.one.useQuery({ mongoId });
|
||||
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
@ -343,7 +342,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -52,14 +52,13 @@ type TabState = "projects" | "monitoring" | "settings" | "backups" | "advanced";
|
||||
const MySql = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
const { mysqlId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
const [tab, setSab] = useState<TabState>(activeTab);
|
||||
const { data } = api.mysql.one.useQuery({ mysqlId });
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
@ -348,7 +347,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -52,7 +52,7 @@ type TabState = "projects" | "monitoring" | "settings" | "backups" | "advanced";
|
||||
const Postgresql = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
const { postgresId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
@ -60,7 +60,6 @@ const Postgresql = (
|
||||
const { data } = api.postgres.one.useQuery({ postgresId });
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
return (
|
||||
@ -345,7 +344,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -51,7 +51,7 @@ type TabState = "projects" | "monitoring" | "settings" | "advanced";
|
||||
const Redis = (
|
||||
props: InferGetServerSidePropsType<typeof getServerSideProps>,
|
||||
) => {
|
||||
const [toggleMonitoring, setToggleMonitoring] = useState(false);
|
||||
const [_toggleMonitoring, _setToggleMonitoring] = useState(false);
|
||||
const { redisId, activeTab } = props;
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
@ -59,7 +59,6 @@ const Redis = (
|
||||
const { data } = api.redis.one.useQuery({ redisId });
|
||||
|
||||
const { data: auth } = api.user.get.useQuery();
|
||||
const { data: monitoring } = api.user.getMetricsToken.useQuery();
|
||||
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
|
||||
@ -335,7 +334,7 @@ export async function getServerSideProps(
|
||||
activeTab: (activeTab || "general") as TabState,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
redirect: {
|
||||
permanent: false,
|
||||
|
@ -68,7 +68,7 @@ export async function getServerSideProps(
|
||||
trpcState: helpers.dehydrate(),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ export async function getServerSideProps(
|
||||
},
|
||||
};
|
||||
}
|
||||
const { req, res, resolvedUrl } = ctx;
|
||||
const { req, res } = ctx;
|
||||
const helpers = createServerSideHelpers({
|
||||
router: appRouter,
|
||||
ctx: {
|
||||
@ -69,7 +69,7 @@ export async function getServerSideProps(
|
||||
trpcState: helpers.dehydrate(),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
|
@ -72,7 +72,7 @@ export async function getServerSideProps(
|
||||
trpcState: helpers.dehydrate(),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
|
@ -72,7 +72,7 @@ export async function getServerSideProps(
|
||||
trpcState: helpers.dehydrate(),
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
|
@ -43,18 +43,11 @@ const LoginSchema = z.object({
|
||||
password: z.string().min(8),
|
||||
});
|
||||
|
||||
const TwoFactorSchema = z.object({
|
||||
const _TwoFactorSchema = z.object({
|
||||
code: z.string().min(6),
|
||||
});
|
||||
|
||||
const BackupCodeSchema = z.object({
|
||||
code: z.string().min(8, {
|
||||
message: "Backup code must be at least 8 characters",
|
||||
}),
|
||||
});
|
||||
|
||||
type LoginForm = z.infer<typeof LoginSchema>;
|
||||
type BackupCodeForm = z.infer<typeof BackupCodeSchema>;
|
||||
|
||||
interface Props {
|
||||
IS_CLOUD: boolean;
|
||||
@ -101,7 +94,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
|
||||
toast.success("Logged in successfully");
|
||||
router.push("/dashboard/projects");
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error("An error occurred while logging in");
|
||||
} finally {
|
||||
setIsLoginLoading(false);
|
||||
@ -117,7 +110,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
|
||||
setIsTwoFactorLoading(true);
|
||||
try {
|
||||
const { data, error } = await authClient.twoFactor.verifyTotp({
|
||||
const { error } = await authClient.twoFactor.verifyTotp({
|
||||
code: twoFactorCode.replace(/\s/g, ""),
|
||||
});
|
||||
|
||||
@ -129,7 +122,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
|
||||
toast.success("Logged in successfully");
|
||||
router.push("/dashboard/projects");
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error("An error occurred while verifying 2FA code");
|
||||
} finally {
|
||||
setIsTwoFactorLoading(false);
|
||||
@ -145,7 +138,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
|
||||
setIsBackupCodeLoading(true);
|
||||
try {
|
||||
const { data, error } = await authClient.twoFactor.verifyBackupCode({
|
||||
const { error } = await authClient.twoFactor.verifyBackupCode({
|
||||
code: backupCode.trim(),
|
||||
});
|
||||
|
||||
@ -159,7 +152,7 @@ export default function Home({ IS_CLOUD }: Props) {
|
||||
|
||||
toast.success("Logged in successfully");
|
||||
router.push("/dashboard/projects");
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error("An error occurred while verifying backup code");
|
||||
} finally {
|
||||
setIsBackupCodeLoading(false);
|
||||
@ -396,7 +389,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
},
|
||||
};
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (_error) {}
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
@ -16,7 +16,6 @@ import { authClient } from "@/lib/auth-client";
|
||||
import { api } from "@/utils/api";
|
||||
import { IS_CLOUD, getUserByToken } from "@dokploy/server";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
@ -90,9 +89,6 @@ const Invitation = ({
|
||||
},
|
||||
);
|
||||
|
||||
const { mutateAsync, error, isError, isSuccess } =
|
||||
api.auth.createUser.useMutation();
|
||||
|
||||
const form = useForm<Register>({
|
||||
defaultValues: {
|
||||
name: "",
|
||||
@ -115,7 +111,7 @@ const Invitation = ({
|
||||
|
||||
const onSubmit = async (values: Register) => {
|
||||
try {
|
||||
const { data, error } = await authClient.signUp.email({
|
||||
const { error } = await authClient.signUp.email({
|
||||
email: values.email,
|
||||
password: values.password,
|
||||
name: values.name,
|
||||
@ -131,13 +127,13 @@ const Invitation = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await authClient.organization.acceptInvitation({
|
||||
const _result = await authClient.organization.acceptInvitation({
|
||||
invitationId: token,
|
||||
});
|
||||
|
||||
toast.success("Account created successfully");
|
||||
router.push("/dashboard/projects");
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
toast.error("An error occurred while creating your account");
|
||||
}
|
||||
};
|
||||
@ -180,14 +176,14 @@ const Invitation = ({
|
||||
<div className="w-full">
|
||||
<div className="p-3" />
|
||||
|
||||
{isError && (
|
||||
{/* {isError && (
|
||||
<div className="mx-5 my-2 flex flex-row items-center gap-2 rounded-lg bg-red-50 p-2 dark:bg-red-950">
|
||||
<AlertTriangle className="text-red-600 dark:text-red-400" />
|
||||
<span className="text-sm text-red-600 dark:text-red-400">
|
||||
{error?.message}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
<CardContent className="p-0">
|
||||
<Form {...form}>
|
||||
@ -313,7 +309,6 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) {
|
||||
const { query } = ctx;
|
||||
|
||||
const token = query.token;
|
||||
console.log("query", query);
|
||||
|
||||
if (typeof token !== "string") {
|
||||
return {
|
||||
|
@ -13,15 +13,15 @@ import {
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import { api } from "@/utils/api";
|
||||
import { IS_CLOUD, isAdminPresent, validateRequest } from "@dokploy/server";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import type { GetServerSidePropsContext } from "next";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { type ReactElement, useEffect } from "react";
|
||||
import { type ReactElement, useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import { z } from "zod";
|
||||
|
||||
const registerSchema = z
|
||||
@ -72,15 +72,16 @@ interface Props {
|
||||
|
||||
const Register = ({ isCloud }: Props) => {
|
||||
const router = useRouter();
|
||||
const { mutateAsync, error, isError, data } =
|
||||
api.auth.createAdmin.useMutation();
|
||||
const [isError, setIsError] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [data, setData] = useState<any>(null);
|
||||
|
||||
const form = useForm<Register>({
|
||||
defaultValues: {
|
||||
name: "Mauricio Siu",
|
||||
email: "user5@yopmail.com",
|
||||
password: "Password1234",
|
||||
confirmPassword: "Password1234",
|
||||
password: "Password123",
|
||||
confirmPassword: "Password123",
|
||||
},
|
||||
resolver: zodResolver(registerSchema),
|
||||
});
|
||||
@ -96,27 +97,19 @@ const Register = ({ isCloud }: Props) => {
|
||||
name: values.name,
|
||||
});
|
||||
|
||||
// const { data, error } = await authClient.admin.createUser({
|
||||
// name: values.name,
|
||||
// email: values.email,
|
||||
// password: values.password,
|
||||
// role: "superAdmin",
|
||||
// });
|
||||
|
||||
// consol/e.log(data, error);
|
||||
// await mutateAsync({
|
||||
// email: values.email.toLowerCase(),
|
||||
// password: values.password,
|
||||
// })
|
||||
// .then(() => {
|
||||
// toast.success("User registered successfuly", {
|
||||
// duration: 2000,
|
||||
// });
|
||||
// if (!isCloud) {
|
||||
// router.push("/");
|
||||
// }
|
||||
// })
|
||||
// .catch((e) => e);
|
||||
if (error) {
|
||||
setIsError(true);
|
||||
setError(error.message || "An error occurred");
|
||||
} else {
|
||||
toast.success("User registered successfuly", {
|
||||
duration: 2000,
|
||||
});
|
||||
if (!isCloud) {
|
||||
router.push("/");
|
||||
} else {
|
||||
setData(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="">
|
||||
@ -138,15 +131,15 @@ const Register = ({ isCloud }: Props) => {
|
||||
</CardDescription>
|
||||
<div className="mx-auto w-full max-w-lg bg-transparent">
|
||||
{isError && (
|
||||
<div className="mx-5 my-2 flex flex-row items-center gap-2 rounded-lg bg-red-50 p-2 dark:bg-red-950">
|
||||
<div className=" my-2 flex flex-row items-center gap-2 rounded-lg bg-red-50 p-2 dark:bg-red-950">
|
||||
<AlertTriangle className="text-red-600 dark:text-red-400" />
|
||||
<span className="text-sm text-red-600 dark:text-red-400">
|
||||
{error?.message}
|
||||
{error}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{data?.type === "cloud" && (
|
||||
<AlertBlock type="success" className="mx-4 my-2">
|
||||
{isCloud && data && (
|
||||
<AlertBlock type="success" className="my-2">
|
||||
<span>
|
||||
Registered successfully, please check your inbox or spam
|
||||
folder to confirm your account.
|
||||
|
@ -77,7 +77,7 @@ export default function Home({ token }: Props) {
|
||||
resetPasswordToken: token,
|
||||
password: values.password,
|
||||
})
|
||||
.then((data) => {
|
||||
.then((_data) => {
|
||||
toast.success("Password reset successfully", {
|
||||
duration: 2000,
|
||||
});
|
||||
|
@ -43,13 +43,13 @@ type AuthResponse = {
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
const [temp, setTemp] = useState<AuthResponse>({
|
||||
const [temp, _setTemp] = useState<AuthResponse>({
|
||||
is2FAEnabled: false,
|
||||
authId: "",
|
||||
});
|
||||
const { mutateAsync, isLoading, isError, error } =
|
||||
api.auth.sendResetPasswordEmail.useMutation();
|
||||
const router = useRouter();
|
||||
const _router = useRouter();
|
||||
const form = useForm<Login>({
|
||||
defaultValues: {
|
||||
email: "",
|
||||
@ -65,7 +65,7 @@ export default function Home() {
|
||||
await mutateAsync({
|
||||
email: values.email,
|
||||
})
|
||||
.then((data) => {
|
||||
.then((_data) => {
|
||||
toast.success("Email sent", {
|
||||
duration: 2000,
|
||||
});
|
||||
@ -150,7 +150,7 @@ export default function Home() {
|
||||
Home.getLayout = (page: ReactElement) => {
|
||||
return <OnboardingLayout>{page}</OnboardingLayout>;
|
||||
};
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
export async function getServerSideProps(_context: GetServerSidePropsContext) {
|
||||
if (!IS_CLOUD) {
|
||||
return {
|
||||
redirect: {
|
||||
|
@ -33,7 +33,7 @@ import {
|
||||
} from "../trpc";
|
||||
|
||||
export const authRouter = createTRPCRouter({
|
||||
createAdmin: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||
createAdmin: publicProcedure.mutation(async ({ input }) => {
|
||||
try {
|
||||
if (!IS_CLOUD) {
|
||||
const admin = await db.query.admins.findFirst({});
|
||||
@ -72,9 +72,9 @@ export const authRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}),
|
||||
createUser: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||
createUser: publicProcedure.mutation(async ({ input }) => {
|
||||
try {
|
||||
const token = await getUserByToken(input.token);
|
||||
const _token = await getUserByToken(input.token);
|
||||
// if (token.isExpired) {
|
||||
// throw new TRPCError({
|
||||
// code: "BAD_REQUEST",
|
||||
@ -103,7 +103,7 @@ export const authRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
login: publicProcedure.mutation(async ({ ctx, input }) => {
|
||||
login: publicProcedure.mutation(async ({ input }) => {
|
||||
try {
|
||||
const auth = await findAuthByEmail(input.email);
|
||||
|
||||
@ -169,7 +169,7 @@ export const authRouter = createTRPCRouter({
|
||||
}),
|
||||
|
||||
logout: protectedProcedure.mutation(async ({ ctx }) => {
|
||||
const { req, res } = ctx;
|
||||
const { req } = ctx;
|
||||
const { session } = await validateRequest(req);
|
||||
if (!session) return false;
|
||||
|
||||
@ -229,7 +229,7 @@ export const authRouter = createTRPCRouter({
|
||||
message: "Password is incorrect",
|
||||
});
|
||||
}
|
||||
const { req, res } = ctx;
|
||||
const { req } = ctx;
|
||||
const { session } = await validateRequest(req);
|
||||
if (!session) return false;
|
||||
|
||||
@ -245,7 +245,7 @@ export const authRouter = createTRPCRouter({
|
||||
return true;
|
||||
}),
|
||||
|
||||
generateToken: protectedProcedure.mutation(async ({ ctx, input }) => {
|
||||
generateToken: protectedProcedure.mutation(async ({ ctx }) => {
|
||||
const auth = await findUserById(ctx.user.id);
|
||||
console.log(auth);
|
||||
|
||||
@ -276,7 +276,7 @@ export const authRouter = createTRPCRouter({
|
||||
email: z.string().min(1).email(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
.mutation(async ({ input }) => {
|
||||
if (!IS_CLOUD) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
@ -329,7 +329,7 @@ export const authRouter = createTRPCRouter({
|
||||
password: z.string().min(1),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
.mutation(async ({ input }) => {
|
||||
if (!IS_CLOUD) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
@ -373,7 +373,7 @@ export const authRouter = createTRPCRouter({
|
||||
confirmationToken: z.string().min(1),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
.mutation(async ({ input }) => {
|
||||
if (!IS_CLOUD) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
mariadb,
|
||||
mongo,
|
||||
mysql,
|
||||
organization,
|
||||
postgres,
|
||||
redis,
|
||||
server,
|
||||
@ -102,6 +103,18 @@ export const serverRouter = createTRPCRouter({
|
||||
|
||||
return result;
|
||||
}),
|
||||
count: protectedProcedure.query(async ({ ctx }) => {
|
||||
const organizations = await db.query.organization.findMany({
|
||||
where: eq(organization.ownerId, ctx.user.id),
|
||||
with: {
|
||||
servers: true,
|
||||
},
|
||||
});
|
||||
|
||||
const servers = organizations.flatMap((org) => org.servers);
|
||||
|
||||
return servers.length ?? 0;
|
||||
}),
|
||||
withSSHKey: protectedProcedure.query(async ({ ctx }) => {
|
||||
const result = await db.query.server.findMany({
|
||||
orderBy: desc(server.createdAt),
|
||||
|
@ -56,7 +56,7 @@ export const stripeRouter = createTRPCRouter({
|
||||
});
|
||||
|
||||
const items = getStripeItems(input.serverQuantity, input.isAnnual);
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
const user = await findUserById(ctx.user.id);
|
||||
|
||||
let stripeCustomerId = user.stripeCustomerId;
|
||||
|
||||
@ -78,7 +78,7 @@ export const stripeRouter = createTRPCRouter({
|
||||
customer: stripeCustomerId,
|
||||
}),
|
||||
metadata: {
|
||||
ownerId: user.id,
|
||||
adminId: user.id,
|
||||
},
|
||||
allow_promotion_codes: true,
|
||||
success_url: `${WEBSITE_URL}/dashboard/settings/servers?success=true`,
|
||||
@ -88,7 +88,7 @@ export const stripeRouter = createTRPCRouter({
|
||||
return { sessionId: session.id };
|
||||
}),
|
||||
createCustomerPortalSession: adminProcedure.mutation(async ({ ctx }) => {
|
||||
const user = await findUserById(ctx.user.ownerId);
|
||||
const user = await findUserById(ctx.user.id);
|
||||
|
||||
if (!user.stripeCustomerId) {
|
||||
throw new TRPCError({
|
||||
|
@ -1,15 +1,10 @@
|
||||
import bc from "bcrypt";
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
|
||||
const connectionString = process.env.DATABASE_URL!;
|
||||
|
||||
const pg = postgres(connectionString, { max: 1 });
|
||||
const db = drizzle(pg);
|
||||
|
||||
function password(txt: string) {
|
||||
return bc.hashSync(txt, 10);
|
||||
}
|
||||
const _db = drizzle(pg);
|
||||
|
||||
async function seed() {
|
||||
console.log("> Seed:", process.env.DATABASE_PATH, "\n");
|
||||
|
@ -6,7 +6,7 @@ export const isWSL = async () => {
|
||||
const { stdout } = await execAsync("uname -r");
|
||||
const isWSL = stdout.includes("microsoft");
|
||||
return isWSL;
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -50,8 +50,8 @@ export const setupDockerContainerTerminalWebSocketServer = (
|
||||
throw new Error("No SSH key available for this server");
|
||||
|
||||
const conn = new Client();
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
let _stdout = "";
|
||||
let _stderr = "";
|
||||
conn
|
||||
.once("ready", () => {
|
||||
conn.exec(
|
||||
@ -61,16 +61,16 @@ export const setupDockerContainerTerminalWebSocketServer = (
|
||||
if (err) throw err;
|
||||
|
||||
stream
|
||||
.on("close", (code: number, signal: string) => {
|
||||
.on("close", (code: number, _signal: string) => {
|
||||
ws.send(`\nContainer closed with code: ${code}\n`);
|
||||
conn.end();
|
||||
})
|
||||
.on("data", (data: string) => {
|
||||
stdout += data.toString();
|
||||
_stdout += data.toString();
|
||||
ws.send(data.toString());
|
||||
})
|
||||
.stderr.on("data", (data) => {
|
||||
stderr += data.toString();
|
||||
_stderr += data.toString();
|
||||
ws.send(data.toString());
|
||||
console.error("Error: ", data.toString());
|
||||
});
|
||||
|
@ -32,7 +32,7 @@ export const setupDrawerLogsWebSocketServer = (
|
||||
});
|
||||
|
||||
wssTerm.on("connection", async (ws, req) => {
|
||||
const url = new URL(req.url || "", `http://${req.headers.host}`);
|
||||
const _url = new URL(req.url || "", `http://${req.headers.host}`);
|
||||
const { user, session } = await validateRequest(req);
|
||||
|
||||
if (!user || !session) {
|
||||
|
@ -103,7 +103,7 @@ export const setupDeploymentLogsWebSocketServer = (
|
||||
ws.close();
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (_error) {
|
||||
// @ts-ignore
|
||||
// const errorMessage = error?.message as unknown as string;
|
||||
// ws.send(errorMessage);
|
||||
|
@ -144,8 +144,8 @@ export const setupTerminalWebSocketServer = (
|
||||
}
|
||||
|
||||
const conn = new Client();
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
let _stdout = "";
|
||||
let _stderr = "";
|
||||
|
||||
ws.send("Connecting...\n");
|
||||
|
||||
@ -158,16 +158,16 @@ export const setupTerminalWebSocketServer = (
|
||||
if (err) throw err;
|
||||
|
||||
stream
|
||||
.on("close", (code: number, signal: string) => {
|
||||
.on("close", (code: number, _signal: string) => {
|
||||
ws.send(`\nContainer closed with code: ${code}\n`);
|
||||
conn.end();
|
||||
})
|
||||
.on("data", (data: string) => {
|
||||
stdout += data.toString();
|
||||
_stdout += data.toString();
|
||||
ws.send(data.toString());
|
||||
})
|
||||
.stderr.on("data", (data) => {
|
||||
stderr += data.toString();
|
||||
_stderr += data.toString();
|
||||
ws.send(data.toString());
|
||||
console.error("Error: ", data.toString());
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
} from "../utils";
|
||||
|
||||
export function generate(schema: Schema): Template {
|
||||
const mainServiceHash = generateHash(schema.projectName);
|
||||
const _mainServiceHash = generateHash(schema.projectName);
|
||||
|
||||
const domains: DomainSchema[] = [
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
} from "../utils";
|
||||
|
||||
export function generate(schema: Schema): Template {
|
||||
const mainServiceHash = generateHash(schema.projectName);
|
||||
const _mainServiceHash = generateHash(schema.projectName);
|
||||
const mainDomain = generateRandomDomain(schema);
|
||||
|
||||
const domains: DomainSchema[] = [
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { Schema, Template } from "../utils";
|
||||
|
||||
export function generate(schema: Schema): Template {
|
||||
export function generate(_schema: Schema): Template {
|
||||
const envs = [`CLOUDFLARE_TUNNEL_TOKEN="<INSERT TOKEN>"`];
|
||||
|
||||
return {
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
|
||||
export function generate(schema: Schema): Template {
|
||||
const mainDomain = generateRandomDomain(schema);
|
||||
const secretKeyBase = generateBase64(64);
|
||||
const _secretKeyBase = generateBase64(64);
|
||||
|
||||
const domains: DomainSchema[] = [
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ export function generate(schema: Schema): Template {
|
||||
const mainDomain = generateRandomDomain(schema);
|
||||
const dbPassword = generatePassword();
|
||||
const dbUser = "immich";
|
||||
const appSecret = generateBase64(32);
|
||||
const _appSecret = generateBase64(32);
|
||||
|
||||
const domains: DomainSchema[] = [
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { Schema, Template } from "../utils";
|
||||
|
||||
export function generate(schema: Schema): Template {
|
||||
export function generate(_schema: Schema): Template {
|
||||
const mounts: Template["mounts"] = [
|
||||
{
|
||||
filePath: "init-mongo.sh",
|
||||
|
@ -28,19 +28,16 @@ export const certificates = pgTable("certificate", {
|
||||
}),
|
||||
});
|
||||
|
||||
export const certificatesRelations = relations(
|
||||
certificates,
|
||||
({ one, many }) => ({
|
||||
server: one(server, {
|
||||
fields: [certificates.serverId],
|
||||
references: [server.serverId],
|
||||
}),
|
||||
organization: one(organization, {
|
||||
fields: [certificates.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
export const certificatesRelations = relations(certificates, ({ one }) => ({
|
||||
server: one(server, {
|
||||
fields: [certificates.serverId],
|
||||
references: [server.serverId],
|
||||
}),
|
||||
);
|
||||
organization: one(organization, {
|
||||
fields: [certificates.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const apiCreateCertificate = createInsertSchema(certificates, {
|
||||
name: z.string().min(1),
|
||||
|
@ -29,7 +29,7 @@ export const gitProvider = pgTable("git_provider", {
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
|
||||
export const gitProviderRelations = relations(gitProvider, ({ one }) => ({
|
||||
github: one(github, {
|
||||
fields: [gitProvider.gitProviderId],
|
||||
references: [github.gitProviderId],
|
||||
|
@ -32,7 +32,7 @@ export const registry = pgTable("registry", {
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const registryRelations = relations(registry, ({ one, many }) => ({
|
||||
export const registryRelations = relations(registry, ({ many }) => ({
|
||||
applications: many(applications),
|
||||
}));
|
||||
|
||||
|
@ -2,14 +2,12 @@ import type { IncomingMessage } from "node:http";
|
||||
import * as bcrypt from "bcrypt";
|
||||
import { betterAuth } from "better-auth";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import {
|
||||
createAuthMiddleware,
|
||||
organization,
|
||||
twoFactor,
|
||||
} from "better-auth/plugins";
|
||||
import { organization, twoFactor } from "better-auth/plugins";
|
||||
import { and, desc, eq } from "drizzle-orm";
|
||||
import { db } from "../db";
|
||||
import * as schema from "../db/schema";
|
||||
import { sendVerificationEmail } from "../verification/send-verification-email";
|
||||
import { IS_CLOUD } from "../constants";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
@ -27,9 +25,18 @@ export const auth = betterAuth({
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
|
||||
},
|
||||
},
|
||||
emailVerification: {
|
||||
sendOnSignUp: true,
|
||||
autoSignInAfterVerification: true,
|
||||
sendVerificationEmail: async ({ user, url }) => {
|
||||
console.log("Sending verification email to", user.email);
|
||||
await sendVerificationEmail(user.email, url);
|
||||
},
|
||||
},
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
|
||||
autoSignIn: !IS_CLOUD,
|
||||
requireEmailVerification: IS_CLOUD,
|
||||
password: {
|
||||
async hash(password) {
|
||||
return bcrypt.hashSync(password, 10);
|
||||
@ -39,33 +46,37 @@ export const auth = betterAuth({
|
||||
},
|
||||
},
|
||||
},
|
||||
hooks: {
|
||||
after: createAuthMiddleware(async (ctx) => {
|
||||
if (ctx.path.startsWith("/sign-up")) {
|
||||
const newSession = ctx.context.newSession;
|
||||
if (ctx.headers?.get("x-dokploy-token")) {
|
||||
} else {
|
||||
const organization = await db
|
||||
.insert(schema.organization)
|
||||
.values({
|
||||
name: "My Organization",
|
||||
ownerId: newSession?.user?.id || "",
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
await db.insert(schema.member).values({
|
||||
userId: newSession?.user?.id || "",
|
||||
organizationId: organization?.id || "",
|
||||
role: "owner",
|
||||
createdAt: new Date(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}),
|
||||
},
|
||||
databaseHooks: {
|
||||
user: {
|
||||
create: {
|
||||
after: async (user) => {
|
||||
const isAdminPresent = await db.query.member.findFirst({
|
||||
where: eq(schema.member.role, "owner"),
|
||||
});
|
||||
|
||||
if (IS_CLOUD || !isAdminPresent) {
|
||||
await db.transaction(async (tx) => {
|
||||
const organization = await tx
|
||||
.insert(schema.organization)
|
||||
.values({
|
||||
name: "My Organization",
|
||||
ownerId: user.id,
|
||||
createdAt: new Date(),
|
||||
})
|
||||
.returning()
|
||||
.then((res) => res[0]);
|
||||
|
||||
await tx.insert(schema.member).values({
|
||||
userId: user.id,
|
||||
organizationId: organization?.id || "",
|
||||
role: "owner",
|
||||
createdAt: new Date(),
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
session: {
|
||||
create: {
|
||||
before: async (session) => {
|
||||
@ -106,7 +117,7 @@ export const auth = betterAuth({
|
||||
plugins: [
|
||||
twoFactor(),
|
||||
organization({
|
||||
async sendInvitationEmail(data, request) {
|
||||
async sendInvitationEmail(data, _request) {
|
||||
const inviteLink = `https://example.com/accept-invitation/${data.id}`;
|
||||
// https://example.com/accept-invitation/8jlBi9Tb9isDb8mc8Sb85u1BaJYklKB2
|
||||
// sendOrganizationInvitation({
|
||||
|
@ -1,94 +0,0 @@
|
||||
// import {
|
||||
// decodeHex,
|
||||
// encodeBase32LowerCaseNoPadding,
|
||||
// encodeHexLowerCase,
|
||||
// } from "@oslojs/encoding";
|
||||
// import { generateRandomString } from "@oslojs/crypto/random";
|
||||
// import { constantTimeEqual } from "@oslojs/crypto/subtle";
|
||||
// import { scrypt } from "./scrypt/index";
|
||||
|
||||
// import type { RandomReader } from "@oslojs/crypto/random";
|
||||
|
||||
// async function generateScryptKey(
|
||||
// data: string,
|
||||
// salt: string,
|
||||
// blockSize = 16,
|
||||
// ): Promise<Uint8Array> {
|
||||
// const encodedData = new TextEncoder().encode(data);
|
||||
// const encodedSalt = new TextEncoder().encode(salt);
|
||||
// const keyUint8Array = await scrypt(encodedData, encodedSalt, {
|
||||
// N: 16384,
|
||||
// r: blockSize,
|
||||
// p: 1,
|
||||
// dkLen: 64,
|
||||
// });
|
||||
// return new Uint8Array(keyUint8Array);
|
||||
// }
|
||||
|
||||
// const random: RandomReader = {
|
||||
// read(bytes: Uint8Array): void {
|
||||
// crypto.getRandomValues(bytes);
|
||||
// },
|
||||
// };
|
||||
|
||||
// export function generateId(length: number): string {
|
||||
// const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
// return generateRandomString(random, alphabet, length);
|
||||
// }
|
||||
|
||||
// export function generateIdFromEntropySize(size: number): string {
|
||||
// const buffer = crypto.getRandomValues(new Uint8Array(size));
|
||||
// return encodeBase32LowerCaseNoPadding(buffer);
|
||||
// }
|
||||
|
||||
// export class Scrypt implements PasswordHashingAlgorithm {
|
||||
// async hash(password: string): Promise<string> {
|
||||
// const salt = encodeHexLowerCase(crypto.getRandomValues(new Uint8Array(16)));
|
||||
// const key = await generateScryptKey(password.normalize("NFKC"), salt);
|
||||
// return `${salt}:${encodeHexLowerCase(key)}`;
|
||||
// }
|
||||
// async verify(hash: string, password: string): Promise<boolean> {
|
||||
// const parts = hash.split(":");
|
||||
// if (parts.length !== 2) return false;
|
||||
|
||||
// const [salt, key] = parts;
|
||||
// const targetKey = await generateScryptKey(password.normalize("NFKC"), salt);
|
||||
// return constantTimeEqual(targetKey, decodeHex(key));
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class LegacyScrypt implements PasswordHashingAlgorithm {
|
||||
// async hash(password: string): Promise<string> {
|
||||
// const salt = encodeHexLowerCase(crypto.getRandomValues(new Uint8Array(16)));
|
||||
// const key = await generateScryptKey(password.normalize("NFKC"), salt);
|
||||
// return `s2:${salt}:${encodeHexLowerCase(key)}`;
|
||||
// }
|
||||
// async verify(hash: string, password: string): Promise<boolean> {
|
||||
// const parts = hash.split(":");
|
||||
// if (parts.length === 2) {
|
||||
// const [salt, key] = parts;
|
||||
// const targetKey = await generateScryptKey(
|
||||
// password.normalize("NFKC"),
|
||||
// salt,
|
||||
// 8,
|
||||
// );
|
||||
// const result = constantTimeEqual(targetKey, decodeHex(key));
|
||||
// return result;
|
||||
// }
|
||||
// if (parts.length !== 3) return false;
|
||||
// const [version, salt, key] = parts;
|
||||
// if (version === "s2") {
|
||||
// const targetKey = await generateScryptKey(
|
||||
// password.normalize("NFKC"),
|
||||
// salt,
|
||||
// );
|
||||
// return constantTimeEqual(targetKey, decodeHex(key));
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export interface PasswordHashingAlgorithm {
|
||||
// hash(password: string): Promise<string>;
|
||||
// verify(hash: string, password: string): Promise<boolean>;
|
||||
// }
|
@ -1 +0,0 @@
|
||||
//
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user