mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-31 09:45:45 +02:00
Merge branch 'dev' into refactor/batch-status-requests
This commit is contained in:
@@ -4,9 +4,13 @@ import { getCachedSubscription } from "./getCachedSubscription";
|
||||
import { priv } from ".";
|
||||
import { AxiosResponse } from "axios";
|
||||
import { GetLicenseStatusResponse } from "@server/routers/license/types";
|
||||
import { Tier } from "@server/types/Tiers";
|
||||
|
||||
export const isOrgSubscribed = cache(async (orgId: string) => {
|
||||
const DEFAULT_PAID_TIERS: Tier[] = ["tier1", "tier2", "tier3", "enterprise"];
|
||||
|
||||
export const isOrgSubscribed = cache(async (orgId: string, tiers?: Tier[]) => {
|
||||
let subscribed = false;
|
||||
const allowedTiers = tiers ?? DEFAULT_PAID_TIERS;
|
||||
|
||||
if (build === "enterprise") {
|
||||
try {
|
||||
@@ -20,7 +24,8 @@ export const isOrgSubscribed = cache(async (orgId: string) => {
|
||||
try {
|
||||
const subRes = await getCachedSubscription(orgId);
|
||||
subscribed =
|
||||
(subRes.data.data.tier == "tier1" || subRes.data.data.tier == "tier2" || subRes.data.data.tier == "tier3" || subRes.data.data.tier == "enterprise") &&
|
||||
!!subRes.data.data.tier &&
|
||||
allowedTiers.includes(subRes.data.data.tier as Tier) &&
|
||||
subRes.data.data.active;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const LAST_USED_IDP_COOKIE_NAME = "p__last_used_idp";
|
||||
@@ -0,0 +1,24 @@
|
||||
import type {
|
||||
Control,
|
||||
FieldValues,
|
||||
UseFormSetValue,
|
||||
UseFormWatch
|
||||
} from "react-hook-form";
|
||||
|
||||
export function asAnyControl<T extends FieldValues>(
|
||||
control: Control<T>
|
||||
): Control<any> {
|
||||
return control as Control<any>;
|
||||
}
|
||||
|
||||
export function asAnySetValue<T extends FieldValues>(
|
||||
setValue: UseFormSetValue<T>
|
||||
): UseFormSetValue<any> {
|
||||
return setValue as UseFormSetValue<any>;
|
||||
}
|
||||
|
||||
export function asAnyWatch<T extends FieldValues>(
|
||||
watch: UseFormWatch<T>
|
||||
): UseFormWatch<any> {
|
||||
return watch as UseFormWatch<any>;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { priv } from "@app/lib/api";
|
||||
import { isOrgSubscribed } from "@app/lib/api/isOrgSubscribed";
|
||||
import { build } from "@server/build";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import { LoadLoginPageBrandingResponse } from "@server/routers/loginPage/types";
|
||||
import { AxiosResponse } from "axios";
|
||||
|
||||
@@ -11,7 +12,10 @@ export async function loadOrgLoginPageBranding(orgId: string): Promise<{
|
||||
return { primaryColor: null };
|
||||
}
|
||||
|
||||
const subscribed = await isOrgSubscribed(orgId);
|
||||
const subscribed = await isOrgSubscribed(
|
||||
orgId,
|
||||
tierMatrix.loginPageBranding
|
||||
);
|
||||
if (!subscribed) {
|
||||
return { primaryColor: null };
|
||||
}
|
||||
|
||||
@@ -165,7 +165,6 @@ export function buildCreateSiteResourcePayload(
|
||||
siteIds: data.siteIds,
|
||||
mode: data.mode,
|
||||
destination: isNativeSsh ? undefined : (data.destination ?? undefined),
|
||||
enabled: true,
|
||||
...(data.mode === "http" && {
|
||||
scheme: data.scheme,
|
||||
ssl: data.ssl ?? false,
|
||||
@@ -342,7 +341,8 @@ export function createGeneralFormSchema(t: TranslateFn) {
|
||||
.string()
|
||||
.min(1)
|
||||
.max(255)
|
||||
.regex(/^[a-zA-Z0-9-]+$/)
|
||||
.regex(/^[a-zA-Z0-9-]+$/),
|
||||
enabled: z.boolean()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
"use client";
|
||||
|
||||
import type { Selectedsite } from "@app/components/site-selector";
|
||||
import type { SiteResourceData } from "@app/lib/privateResourceForm";
|
||||
|
||||
export function buildSelectedSitesForResource(
|
||||
resource: Pick<SiteResourceData, "siteIds" | "siteNames">
|
||||
): Selectedsite[] {
|
||||
return resource.siteIds.map((siteId, idx) => ({
|
||||
name: resource.siteNames[idx] ?? "",
|
||||
siteId,
|
||||
type: "newt" as const
|
||||
}));
|
||||
}
|
||||
|
||||
export function getSshSingleSiteMode(
|
||||
authDaemonMode?: string | null,
|
||||
pamMode?: string | null
|
||||
): boolean {
|
||||
return (
|
||||
authDaemonMode === "native" ||
|
||||
(pamMode === "push" && authDaemonMode === "site")
|
||||
);
|
||||
}
|
||||
|
||||
export function getSshUseMultiSiteTargetForm(
|
||||
isNative: boolean,
|
||||
authDaemonMode?: string | null,
|
||||
pamMode?: string | null
|
||||
): boolean {
|
||||
if (isNative) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return authDaemonMode !== "site" || pamMode === "passthrough";
|
||||
}
|
||||
+12
-5
@@ -672,9 +672,13 @@ export const orgQueries = {
|
||||
queryOptions({
|
||||
queryKey: ["SITE_STATUS_HISTORY", siteId, days] as const,
|
||||
queryFn: async ({ signal, meta }) => {
|
||||
const tzOffsetMinutes = -new Date().getTimezoneOffset();
|
||||
const res = await meta!.api.get<
|
||||
AxiosResponse<StatusHistoryResponse>
|
||||
>(`/site/${siteId}/status-history?days=${days}`, { signal });
|
||||
>(
|
||||
`/site/${siteId}/status-history?days=${days}&tzOffsetMinutes=${tzOffsetMinutes}`,
|
||||
{ signal }
|
||||
);
|
||||
return res.data.data;
|
||||
}
|
||||
}),
|
||||
@@ -689,11 +693,13 @@ export const orgQueries = {
|
||||
queryOptions({
|
||||
queryKey: ["RESOURCE_STATUS_HISTORY", resourceId, days] as const,
|
||||
queryFn: async ({ signal, meta }) => {
|
||||
const tzOffsetMinutes = -new Date().getTimezoneOffset();
|
||||
const res = await meta!.api.get<
|
||||
AxiosResponse<StatusHistoryResponse>
|
||||
>(`/resource/${resourceId}/status-history?days=${days}`, {
|
||||
signal
|
||||
});
|
||||
>(
|
||||
`/resource/${resourceId}/status-history?days=${days}&tzOffsetMinutes=${tzOffsetMinutes}`,
|
||||
{ signal }
|
||||
);
|
||||
return res.data.data;
|
||||
}
|
||||
}),
|
||||
@@ -715,10 +721,11 @@ export const orgQueries = {
|
||||
days
|
||||
] as const,
|
||||
queryFn: async ({ signal, meta }) => {
|
||||
const tzOffsetMinutes = -new Date().getTimezoneOffset();
|
||||
const res = await meta!.api.get<
|
||||
AxiosResponse<StatusHistoryResponse>
|
||||
>(
|
||||
`/org/${orgId}/health-check/${healthCheckId}/status-history?days=${days}`,
|
||||
`/org/${orgId}/health-check/${healthCheckId}/status-history?days=${days}&tzOffsetMinutes=${tzOffsetMinutes}`,
|
||||
{ signal }
|
||||
);
|
||||
return res.data.data;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Set a cookie on the client side in javascript code, not on the server
|
||||
* @param name
|
||||
* @param value
|
||||
* @param days
|
||||
* @param options
|
||||
*/
|
||||
export function setClientCookie(
|
||||
name: string,
|
||||
value: string,
|
||||
options: {
|
||||
days?: number;
|
||||
path?: string;
|
||||
secure?: boolean;
|
||||
sameSite?: "Strict" | "Lax" | "None";
|
||||
} = {}
|
||||
): void {
|
||||
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
||||
|
||||
if (options.days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + options.days * 864e5);
|
||||
cookie += `; expires=${date.toUTCString()}`;
|
||||
}
|
||||
|
||||
cookie += `; path=${options.path ?? "/"}`;
|
||||
|
||||
if (options.secure) cookie += "; Secure";
|
||||
if (options.sameSite) cookie += `; SameSite=${options.sameSite}`;
|
||||
|
||||
document.cookie = cookie;
|
||||
}
|
||||
Reference in New Issue
Block a user