Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
ffa99ac3d8 Bump the prod-minor-updates group across 1 directory with 4 updates
Bumps the prod-minor-updates group with 4 updates in the / directory: [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3), [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react), [react-day-picker](https://github.com/gpbl/react-day-picker) and [stripe](https://github.com/stripe/stripe-node).


Updates `@aws-sdk/client-s3` from 3.989.0 to 3.999.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.999.0/clients/client-s3)

Updates `lucide-react` from 0.563.0 to 0.575.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.575.0/packages/lucide-react)

Updates `react-day-picker` from 9.13.2 to 9.14.0
- [Release notes](https://github.com/gpbl/react-day-picker/releases)
- [Changelog](https://github.com/gpbl/react-day-picker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gpbl/react-day-picker/compare/v9.13.2...v9.14.0)

Updates `stripe` from 20.3.1 to 20.4.0
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v20.3.1...v20.4.0)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-s3"
  dependency-version: 3.999.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: lucide-react
  dependency-version: 0.575.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: react-day-picker
  dependency-version: 9.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: stripe
  dependency-version: 20.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 01:38:03 +00:00
13 changed files with 715 additions and 875 deletions

View File

@@ -1,5 +1,4 @@
# FROM node:24-slim AS base
FROM public.ecr.aws/docker/library/node:24-slim AS base
FROM node:24-slim AS base
WORKDIR /app
@@ -32,8 +31,7 @@ FROM base AS builder
RUN npm ci --omit=dev
# FROM node:24-slim AS runner
FROM public.ecr.aws/docker/library/node:24-slim AS runner
FROM node:24-slim AS runner
WORKDIR /app

1347
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,7 @@
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "8.4.1",
"@aws-sdk/client-s3": "3.989.0",
"@aws-sdk/client-s3": "3.999.0",
"@faker-js/faker": "10.3.0",
"@headlessui/react": "2.2.9",
"@hookform/resolvers": "5.2.2",
@@ -89,7 +89,7 @@
"jmespath": "0.16.0",
"js-yaml": "4.1.1",
"jsonwebtoken": "9.0.3",
"lucide-react": "0.563.0",
"lucide-react": "0.575.0",
"maxmind": "5.0.5",
"moment": "2.30.1",
"next": "15.5.12",
@@ -103,7 +103,7 @@
"posthog-node": "5.26.0",
"qrcode.react": "4.2.0",
"react": "19.2.4",
"react-day-picker": "9.13.2",
"react-day-picker": "9.14.0",
"react-dom": "19.2.4",
"react-easy-sort": "1.8.0",
"react-hook-form": "7.71.2",
@@ -113,7 +113,7 @@
"resend": "6.9.2",
"semver": "7.7.4",
"sshpk": "^1.18.0",
"stripe": "20.3.1",
"stripe": "20.4.0",
"swagger-ui-express": "5.0.1",
"tailwind-merge": "3.5.0",
"topojson-client": "3.1.0",

View File

@@ -119,12 +119,12 @@ const listClientsSchema = z.object({
}),
query: z.string().optional(),
sort_by: z
.enum(["name", "megabytesIn", "megabytesOut"])
.enum(["megabytesIn", "megabytesOut"])
.optional()
.catch(undefined)
.openapi({
type: "string",
enum: ["name", "megabytesIn", "megabytesOut"],
enum: ["megabytesIn", "megabytesOut"],
description: "Field to sort by"
}),
order: z
@@ -363,7 +363,7 @@ export async function listClients(
const countQuery = db.$count(baseQuery.as("filtered_clients"));
const listMachinesQuery = baseQuery
.limit(pageSize)
.limit(page)
.offset(pageSize * (page - 1))
.orderBy(
sort_by

View File

@@ -19,7 +19,6 @@ import {
and,
asc,
count,
desc,
eq,
inArray,
isNull,
@@ -64,26 +63,6 @@ const listResourcesSchema = z.object({
description: "Page number to retrieve"
}),
query: z.string().optional(),
sort_by: z
.enum(["name"])
.optional()
.catch(undefined)
.openapi({
type: "string",
enum: ["name"],
description: "Field to sort by"
}),
order: z
.enum(["asc", "desc"])
.optional()
.default("asc")
.catch("asc")
.openapi({
type: "string",
enum: ["asc", "desc"],
default: "asc",
description: "Sort order"
}),
enabled: z
.enum(["true", "false"])
.transform((v) => v === "true")
@@ -250,16 +229,8 @@ export async function listResources(
)
);
}
const {
page,
pageSize,
authState,
enabled,
query,
healthStatus,
sort_by,
order
} = parsedQuery.data;
const { page, pageSize, authState, enabled, query, healthStatus } =
parsedQuery.data;
const parsedParams = listResourcesParamsSchema.safeParse(req.params);
if (!parsedParams.success) {
@@ -424,13 +395,7 @@ export async function listResources(
baseQuery
.limit(pageSize)
.offset(pageSize * (page - 1))
.orderBy(
sort_by
? order === "asc"
? asc(resources[sort_by])
: desc(resources[sort_by])
: asc(resources.resourceId)
),
.orderBy(asc(resources.resourceId)),
countQuery
]);

View File

@@ -108,12 +108,12 @@ const listSitesSchema = z.object({
}),
query: z.string().optional(),
sort_by: z
.enum(["name", "megabytesIn", "megabytesOut"])
.enum(["megabytesIn", "megabytesOut"])
.optional()
.catch(undefined)
.openapi({
type: "string",
enum: ["name", "megabytesIn", "megabytesOut"],
enum: ["megabytesIn", "megabytesOut"],
description: "Field to sort by"
}),
order: z
@@ -278,7 +278,7 @@ export async function listSites(
// we need to add `as` so that drizzle filters the result as a subquery
const countQuery = db.$count(
querySitesBase().where(and(...conditions)).as("filtered_sites")
querySitesBase().where(and(...conditions))
);
const siteListQuery = baseQuery

View File

@@ -4,7 +4,7 @@ import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi";
import HttpCode from "@server/types/HttpCode";
import type { PaginatedResponse } from "@server/types/Pagination";
import { and, asc, desc, eq, like, or, sql } from "drizzle-orm";
import { and, asc, eq, like, or, sql } from "drizzle-orm";
import { NextFunction, Request, Response } from "express";
import createHttpError from "http-errors";
import { z } from "zod";
@@ -48,26 +48,6 @@ const listAllSiteResourcesByOrgQuerySchema = z.object({
type: "string",
enum: ["host", "cidr"],
description: "Filter site resources by mode"
}),
sort_by: z
.enum(["name"])
.optional()
.catch(undefined)
.openapi({
type: "string",
enum: ["name"],
description: "Field to sort by"
}),
order: z
.enum(["asc", "desc"])
.optional()
.default("asc")
.catch("asc")
.openapi({
type: "string",
enum: ["asc", "desc"],
default: "asc",
description: "Sort order"
})
});
@@ -151,8 +131,7 @@ export async function listAllSiteResourcesByOrg(
}
const { orgId } = parsedParams.data;
const { page, pageSize, query, mode, sort_by, order } =
parsedQuery.data;
const { page, pageSize, query, mode } = parsedQuery.data;
const conditions = [and(eq(siteResources.orgId, orgId))];
if (query) {
@@ -193,20 +172,14 @@ export async function listAllSiteResourcesByOrg(
const baseQuery = querySiteResourcesBase().where(and(...conditions));
const countQuery = db.$count(
querySiteResourcesBase().where(and(...conditions)).as("filtered_site_resources")
querySiteResourcesBase().where(and(...conditions))
);
const [siteResourcesList, totalCount] = await Promise.all([
baseQuery
.limit(pageSize)
.offset(pageSize * (page - 1))
.orderBy(
sort_by
? order === "asc"
? asc(siteResources[sort_by])
: desc(siteResources[sort_by])
: asc(siteResources.siteResourceId)
),
.orderBy(asc(siteResources.siteResourceId)),
countQuery
]);

View File

@@ -5,7 +5,7 @@ import { siteResources, sites, SiteResource } from "@server/db";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { and, asc, desc, eq } from "drizzle-orm";
import { eq, and } from "drizzle-orm";
import { fromError } from "zod-validation-error";
import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi";
@@ -27,16 +27,7 @@ const listSiteResourcesQuerySchema = z.object({
.optional()
.default("0")
.transform(Number)
.pipe(z.int().nonnegative()),
sort_by: z
.enum(["name"])
.optional()
.catch(undefined),
order: z
.enum(["asc", "desc"])
.optional()
.default("asc")
.catch("asc")
.pipe(z.int().nonnegative())
});
export type ListSiteResourcesResponse = {
@@ -84,7 +75,7 @@ export async function listSiteResources(
}
const { siteId, orgId } = parsedParams.data;
const { limit, offset, sort_by, order } = parsedQuery.data;
const { limit, offset } = parsedQuery.data;
// Verify the site exists and belongs to the org
const site = await db
@@ -107,13 +98,6 @@ export async function listSiteResources(
eq(siteResources.orgId, orgId)
)
)
.orderBy(
sort_by
? order === "asc"
? asc(siteResources[sort_by])
: desc(siteResources[sort_by])
: asc(siteResources.siteResourceId)
)
.limit(limit)
.offset(offset);

View File

@@ -3,12 +3,11 @@ import { redirect } from "next/navigation";
import DeviceLoginForm from "@/components/DeviceLoginForm";
import { getUserDisplayName } from "@app/lib/getUserDisplayName";
import { cache } from "react";
import { cleanRedirect } from "@app/lib/cleanRedirect";
export const dynamic = "force-dynamic";
type Props = {
searchParams: Promise<{ code?: string; user?: string; authPath?: string }>;
searchParams: Promise<{ code?: string; user?: string }>;
};
function deviceRedirectSearchParams(params: {
@@ -31,11 +30,11 @@ export default async function DeviceLoginPage({ searchParams }: Props) {
if (!user) {
const redirectDestination = `/auth/login/device${deviceRedirectSearchParams({ code, user: params.user })}`;
const authPath = cleanRedirect(params.authPath || "/auth/login");
const loginUrl = new URL(authPath, "http://x");
const loginUrl = new URL("/auth/login", "http://x");
loginUrl.searchParams.set("forceLogin", "true");
loginUrl.searchParams.set("redirect", redirectDestination);
if (defaultUser) loginUrl.searchParams.set("user", defaultUser);
console.log("loginUrl", loginUrl.pathname + loginUrl.search);
redirect(loginUrl.pathname + loginUrl.search);
}

View File

@@ -15,15 +15,7 @@ import { InfoPopup } from "@app/components/ui/info-popup";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { toast } from "@app/hooks/useToast";
import { createApiClient, formatAxiosError } from "@app/lib/api";
import { getNextSortOrder, getSortDirection } from "@app/lib/sortColumn";
import {
ArrowDown01Icon,
ArrowUp10Icon,
ArrowUpDown,
ArrowUpRight,
ChevronsUpDownIcon,
MoreHorizontal
} from "lucide-react";
import { ArrowUpDown, ArrowUpRight, MoreHorizontal } from "lucide-react";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { useRouter } from "next/navigation";
@@ -141,26 +133,7 @@ export default function ClientResourcesTable({
accessorKey: "name",
enableHiding: false,
friendlyName: t("name"),
header: () => {
const nameOrder = getSortDirection("name", searchParams);
const Icon =
nameOrder === "asc"
? ArrowDown01Icon
: nameOrder === "desc"
? ArrowUp10Icon
: ChevronsUpDownIcon;
return (
<Button
variant="ghost"
className="p-3"
onClick={() => toggleSort("name")}
>
{t("name")}
<Icon className="ml-2 h-4 w-4" />
</Button>
);
}
header: () => <span className="p-3">{t("name")}</span>
},
{
id: "niceId",
@@ -356,14 +329,6 @@ export default function ClientResourcesTable({
});
}
function toggleSort(column: string) {
const newSearch = getNextSortOrder(column, searchParams);
filter({
searchParams: newSearch
});
}
const handlePaginationChange = (newPage: PaginationState) => {
searchParams.set("page", (newPage.pageIndex + 1).toString());
searchParams.set("pageSize", newPage.pageSize.toString());

View File

@@ -204,26 +204,7 @@ export default function MachineClientsTable({
accessorKey: "name",
enableHiding: false,
friendlyName: t("name"),
header: () => {
const nameOrder = getSortDirection("name", searchParams);
const Icon =
nameOrder === "asc"
? ArrowDown01Icon
: nameOrder === "desc"
? ArrowUp10Icon
: ChevronsUpDownIcon;
return (
<Button
variant="ghost"
onClick={() => toggleSort("name")}
className="px-3"
>
{t("name")}
<Icon className="ml-2 h-4 w-4" />
</Button>
);
},
header: () => <span className="px-3">{t("name")}</span>,
cell: ({ row }) => {
const r = row.original;
return (

View File

@@ -14,19 +14,15 @@ import { InfoPopup } from "@app/components/ui/info-popup";
import { Switch } from "@app/components/ui/switch";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useNavigationContext } from "@app/hooks/useNavigationContext";
import { getNextSortOrder, getSortDirection } from "@app/lib/sortColumn";
import { toast } from "@app/hooks/useToast";
import { createApiClient, formatAxiosError } from "@app/lib/api";
import { UpdateResourceResponse } from "@server/routers/resource";
import type { PaginationState } from "@tanstack/react-table";
import { AxiosResponse } from "axios";
import {
ArrowDown01Icon,
ArrowRight,
ArrowUp10Icon,
CheckCircle2,
ChevronDown,
ChevronsUpDownIcon,
Clock,
MoreHorizontal,
ShieldCheck,
@@ -322,26 +318,7 @@ export default function ProxyResourcesTable({
accessorKey: "name",
enableHiding: false,
friendlyName: t("name"),
header: () => {
const nameOrder = getSortDirection("name", searchParams);
const Icon =
nameOrder === "asc"
? ArrowDown01Icon
: nameOrder === "desc"
? ArrowUp10Icon
: ChevronsUpDownIcon;
return (
<Button
variant="ghost"
className="p-3"
onClick={() => toggleSort("name")}
>
{t("name")}
<Icon className="ml-2 h-4 w-4" />
</Button>
);
}
header: () => <span className="p-3">{t("name")}</span>
},
{
id: "niceId",
@@ -586,14 +563,6 @@ export default function ProxyResourcesTable({
});
}
function toggleSort(column: string) {
const newSearch = getNextSortOrder(column, searchParams);
filter({
searchParams: newSearch
});
}
const handlePaginationChange = (newPage: PaginationState) => {
searchParams.set("page", (newPage.pageIndex + 1).toString());
searchParams.set("pageSize", newPage.pageSize.toString());

View File

@@ -141,24 +141,7 @@ export default function SitesTable({
accessorKey: "name",
enableHiding: false,
header: () => {
const nameOrder = getSortDirection("name", searchParams);
const Icon =
nameOrder === "asc"
? ArrowDown01Icon
: nameOrder === "desc"
? ArrowUp10Icon
: ChevronsUpDownIcon;
return (
<Button
variant="ghost"
className="p-3"
onClick={() => toggleSort("name")}
>
{t("name")}
<Icon className="ml-2 h-4 w-4" />
</Button>
);
return <span className="p-3">{t("name")}</span>;
}
},
{