Handle getting resources

This commit is contained in:
Owen
2026-04-23 17:12:56 -07:00
parent 1ba7fca798
commit 5e293e8364
2 changed files with 65 additions and 8 deletions

View File

@@ -25,7 +25,7 @@ import {
ResourceHeaderAuthExtendedCompatibility,
resourceHeaderAuthExtendedCompatibility
} from "@server/db";
import { and, eq, inArray } from "drizzle-orm";
import { and, eq, inArray, or, sql } from "drizzle-orm";
export type ResourceWithAuth = {
resource: Resource | null;
@@ -47,7 +47,17 @@ export type UserSessionWithUser = {
export async function getResourceByDomain(
domain: string
): Promise<ResourceWithAuth | null> {
const [result] = await db
// Build wildcard domain variants to match against.
// For a domain like "me.example.test.com", we want to match:
// - "*.example.test.com" (subdomain wildcard)
// - "*.test.com" (parent wildcard, i.e. just "*" subdomain on parent)
const parts = domain.split(".");
const wildcardCandidates: string[] = [];
for (let i = 1; i < parts.length; i++) {
wildcardCandidates.push(`*.${parts.slice(i).join(".")}`);
}
const potentialResults = await db
.select()
.from(resources)
.leftJoin(
@@ -70,8 +80,29 @@ export async function getResourceByDomain(
)
)
.innerJoin(orgs, eq(orgs.orgId, resources.orgId))
.where(eq(resources.fullDomain, domain))
.limit(1);
.where(
or(
// Exact match
eq(resources.fullDomain, domain),
// Wildcard match: resource fullDomain is one of the wildcard candidates
wildcardCandidates.length > 0
? and(
eq(resources.wildcard, true),
inArray(resources.fullDomain, wildcardCandidates)
)
: sql`false`
)
);
if (!potentialResults.length) {
return null;
}
// Prefer exact match over wildcard match
const exactMatch = potentialResults.find(
(r) => r.resources?.fullDomain === domain
);
const result = exactMatch ?? potentialResults[0];
if (!result) {
return null;

View File

@@ -50,7 +50,7 @@ import {
userOrgRoles,
roles
} from "@server/db";
import { eq, and, inArray, isNotNull, ne } from "drizzle-orm";
import { eq, and, inArray, isNotNull, ne, or, sql } from "drizzle-orm";
import { response } from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import { NextFunction, Request, Response } from "express";
@@ -492,7 +492,15 @@ hybridRouter.get(
);
}
const [result] = await db
// Build wildcard domain candidates for the requested domain.
// e.g. "me.example.test.com" -> ["*.example.test.com", "*.test.com"]
const domainParts = domain.split(".");
const wildcardCandidates: string[] = [];
for (let i = 1; i < domainParts.length; i++) {
wildcardCandidates.push(`*.${domainParts.slice(i).join(".")}`);
}
const potentialResults = await db
.select()
.from(resources)
.leftJoin(
@@ -515,10 +523,28 @@ hybridRouter.get(
)
)
.innerJoin(orgs, eq(orgs.orgId, resources.orgId))
.where(eq(resources.fullDomain, domain))
.limit(1);
.where(
or(
// Exact match
eq(resources.fullDomain, domain),
// Wildcard match
wildcardCandidates.length > 0
? and(
eq(resources.wildcard, true),
inArray(resources.fullDomain, wildcardCandidates)
)
: sql`false`
)
);
// Prefer exact match over wildcard match
const exactMatch = potentialResults.find(
(r) => r.resources?.fullDomain === domain
);
const result = exactMatch ?? potentialResults[0];
if (
result &&
await checkExitNodeOrg(
remoteExitNode.exitNodeId,
result.resources.orgId