mirror of
https://github.com/fosrl/pangolin.git
synced 2026-01-28 22:00:51 +00:00
206 lines
5.8 KiB
TypeScript
206 lines
5.8 KiB
TypeScript
import { join } from "path";
|
|
import { readFileSync } from "fs";
|
|
import { clients, db, resources, siteResources } from "@server/db";
|
|
import { randomInt } from "crypto";
|
|
import { exitNodes, sites } from "@server/db";
|
|
import { eq, and } from "drizzle-orm";
|
|
import { __DIRNAME } from "@server/lib/consts";
|
|
|
|
// Load the names from the names.json file
|
|
const dev = process.env.ENVIRONMENT !== "prod";
|
|
let file;
|
|
if (!dev) {
|
|
file = join(__DIRNAME, "names.json");
|
|
} else {
|
|
file = join("server/db/names.json");
|
|
}
|
|
export const names = JSON.parse(readFileSync(file, "utf-8"));
|
|
|
|
// Load iOS and Mac model mappings
|
|
let iosModelsFile: string;
|
|
let macModelsFile: string;
|
|
if (!dev) {
|
|
iosModelsFile = join(__DIRNAME, "ios_models.json");
|
|
macModelsFile = join(__DIRNAME, "mac_models.json");
|
|
} else {
|
|
iosModelsFile = join("server/db/ios_models.json");
|
|
macModelsFile = join("server/db/mac_models.json");
|
|
}
|
|
|
|
const iosModels: Record<string, string> = JSON.parse(
|
|
readFileSync(iosModelsFile, "utf-8")
|
|
);
|
|
const macModels: Record<string, string> = JSON.parse(
|
|
readFileSync(macModelsFile, "utf-8")
|
|
);
|
|
|
|
export async function getUniqueClientName(orgId: string): Promise<string> {
|
|
let loops = 0;
|
|
while (true) {
|
|
if (loops > 100) {
|
|
throw new Error("Could not generate a unique name");
|
|
}
|
|
|
|
const name = generateName();
|
|
const count = await db
|
|
.select({ niceId: clients.niceId, orgId: clients.orgId })
|
|
.from(clients)
|
|
.where(and(eq(clients.niceId, name), eq(clients.orgId, orgId)));
|
|
if (count.length === 0) {
|
|
return name;
|
|
}
|
|
loops++;
|
|
}
|
|
}
|
|
|
|
export async function getUniqueSiteName(orgId: string): Promise<string> {
|
|
let loops = 0;
|
|
while (true) {
|
|
if (loops > 100) {
|
|
throw new Error("Could not generate a unique name");
|
|
}
|
|
|
|
const name = generateName();
|
|
const count = await db
|
|
.select({ niceId: sites.niceId, orgId: sites.orgId })
|
|
.from(sites)
|
|
.where(and(eq(sites.niceId, name), eq(sites.orgId, orgId)));
|
|
if (count.length === 0) {
|
|
return name;
|
|
}
|
|
loops++;
|
|
}
|
|
}
|
|
|
|
export async function getUniqueResourceName(orgId: string): Promise<string> {
|
|
let loops = 0;
|
|
while (true) {
|
|
if (loops > 100) {
|
|
throw new Error("Could not generate a unique name");
|
|
}
|
|
|
|
const name = generateName();
|
|
const [resourceCount, siteResourceCount] = await Promise.all([
|
|
db
|
|
.select({ niceId: resources.niceId, orgId: resources.orgId })
|
|
.from(resources)
|
|
.where(
|
|
and(eq(resources.niceId, name), eq(resources.orgId, orgId))
|
|
),
|
|
db
|
|
.select({
|
|
niceId: siteResources.niceId,
|
|
orgId: siteResources.orgId
|
|
})
|
|
.from(siteResources)
|
|
.where(
|
|
and(
|
|
eq(siteResources.niceId, name),
|
|
eq(siteResources.orgId, orgId)
|
|
)
|
|
)
|
|
]);
|
|
if (resourceCount.length === 0 && siteResourceCount.length === 0) {
|
|
return name;
|
|
}
|
|
loops++;
|
|
}
|
|
}
|
|
|
|
export async function getUniqueSiteResourceName(
|
|
orgId: string
|
|
): Promise<string> {
|
|
let loops = 0;
|
|
while (true) {
|
|
if (loops > 100) {
|
|
throw new Error("Could not generate a unique name");
|
|
}
|
|
|
|
const name = generateName();
|
|
const [resourceCount, siteResourceCount] = await Promise.all([
|
|
db
|
|
.select({ niceId: resources.niceId, orgId: resources.orgId })
|
|
.from(resources)
|
|
.where(
|
|
and(eq(resources.niceId, name), eq(resources.orgId, orgId))
|
|
),
|
|
db
|
|
.select({
|
|
niceId: siteResources.niceId,
|
|
orgId: siteResources.orgId
|
|
})
|
|
.from(siteResources)
|
|
.where(
|
|
and(
|
|
eq(siteResources.niceId, name),
|
|
eq(siteResources.orgId, orgId)
|
|
)
|
|
)
|
|
]);
|
|
if (resourceCount.length === 0 && siteResourceCount.length === 0) {
|
|
return name;
|
|
}
|
|
loops++;
|
|
}
|
|
}
|
|
|
|
export async function getUniqueExitNodeEndpointName(): Promise<string> {
|
|
let loops = 0;
|
|
const count = await db.select().from(exitNodes);
|
|
while (true) {
|
|
if (loops > 100) {
|
|
throw new Error("Could not generate a unique name");
|
|
}
|
|
|
|
const name = generateName();
|
|
|
|
for (const node of count) {
|
|
if (node.endpoint.includes(name)) {
|
|
loops++;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return name;
|
|
}
|
|
}
|
|
|
|
export function generateName(): string {
|
|
const name = (
|
|
names.descriptors[randomInt(names.descriptors.length)] +
|
|
"-" +
|
|
names.animals[randomInt(names.animals.length)]
|
|
)
|
|
.toLowerCase()
|
|
.replace(/\s/g, "-");
|
|
|
|
// clean out any non-alphanumeric characters except for dashes
|
|
return name.replace(/[^a-z0-9-]/g, "");
|
|
}
|
|
|
|
export function getMacDeviceName(macIdentifier?: string | null): string | null {
|
|
if (macIdentifier && macModels[macIdentifier]) {
|
|
return macModels[macIdentifier];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function getIosDeviceName(iosIdentifier?: string | null): string | null {
|
|
if (iosIdentifier && iosModels[iosIdentifier]) {
|
|
return iosModels[iosIdentifier];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function getUserDeviceName(
|
|
model: string | null,
|
|
fallBack: string | null
|
|
): string {
|
|
return (
|
|
getMacDeviceName(model) ||
|
|
getIosDeviceName(model) ||
|
|
fallBack ||
|
|
"Unknown Device"
|
|
);
|
|
}
|