Fix merge conflicts

This commit is contained in:
Tuan Dang
2025-04-30 18:32:56 -07:00
149 changed files with 2974 additions and 304 deletions
+13
View File
@@ -1912,6 +1912,10 @@ export const AppConnections = {
TEAMCITY: {
instanceUrl: "The TeamCity instance URL to connect with.",
accessToken: "The access token to use to connect with TeamCity."
},
AZURE_CLIENT_SECRETS: {
code: "The OAuth code to use to connect with Azure Client Secrets.",
tenantId: "The Tenant ID to use to connect with Azure Client Secrets."
}
}
};
@@ -2120,6 +2124,11 @@ export const SecretRotations = {
AUTH0_CLIENT_SECRET: {
clientId: "The client ID of the Auth0 Application to rotate the client secret for."
},
AZURE_CLIENT_SECRET: {
objectId: "The ID of the Azure Application to rotate the client secret for.",
appName: "The name of the Azure Application to rotate the client secret for.",
clientId: "The client ID of the Azure Application to rotate the client secret for."
},
LDAP_PASSWORD: {
dn: "The Distinguished Name (DN) of the principal to rotate the password for."
},
@@ -2150,6 +2159,10 @@ export const SecretRotations = {
clientId: "The name of the secret that the client ID will be mapped to.",
clientSecret: "The name of the secret that the rotated client secret will be mapped to."
},
AZURE_CLIENT_SECRET: {
clientId: "The name of the secret that the client ID will be mapped to.",
clientSecret: "The name of the secret that the rotated client secret will be mapped to."
},
LDAP_PASSWORD: {
dn: "The name of the secret that the Distinguished Name (DN) of the principal will be mapped to.",
password: "The name of the secret that the rotated password will be mapped to."
+3 -3
View File
@@ -2,7 +2,7 @@ export const daysToMillisecond = (days: number) => days * 24 * 60 * 60 * 1000;
export const secondsToMillis = (seconds: number) => seconds * 1000;
export const applyJitter = (delayMs: number, jitterMs: number) => {
const jitter = Math.floor(Math.random() * (2 * jitterMs)) - jitterMs;
return delayMs + jitter;
export const applyJitter = (delay: number, jitter: number) => {
const jitterTime = Math.floor(Math.random() * (2 * jitter)) - jitter;
return delay + jitterTime;
};
+1
View File
@@ -6,4 +6,5 @@ export * from "./array";
export * from "./dates";
export * from "./object";
export * from "./string";
export * from "./time";
export * from "./undefined";
+21
View File
@@ -0,0 +1,21 @@
import ms, { StringValue } from "ms";
const convertToMilliseconds = (exp: string | number): number => {
if (typeof exp === "number") {
return exp * 1000;
}
const result = ms(exp as StringValue);
if (typeof result !== "number") {
throw new Error(`Invalid expiration format: ${exp}`);
}
return result;
};
export const getMinExpiresIn = (exp1: string | number, exp2: string | number): string | number => {
const ms1 = convertToMilliseconds(exp1);
const ms2 = convertToMilliseconds(exp2);
return ms1 <= ms2 ? exp1 : exp2;
};
+20 -5
View File
@@ -2,6 +2,8 @@
import { Knex } from "knex";
import { Tables } from "knex/types/tables";
import { TableName } from "@app/db/schemas";
import { DatabaseError } from "../errors";
import { buildDynamicKnexQuery, TKnexDynamicOperator } from "./dynamic";
@@ -25,28 +27,41 @@ export type TFindFilter<R extends object = object> = Partial<R> & {
$search?: Partial<{ [k in keyof R]: R[k] }>;
$complex?: TKnexDynamicOperator<R>;
};
export const buildFindFilter =
<R extends object = object>({ $in, $notNull, $search, $complex, ...filter }: TFindFilter<R>) =>
<R extends object = object>(
{ $in, $notNull, $search, $complex, ...filter }: TFindFilter<R>,
tableName?: TableName,
excludeKeys?: Array<keyof R>
) =>
(bd: Knex.QueryBuilder<R, R>) => {
void bd.where(filter);
const processedFilter = tableName
? Object.fromEntries(
Object.entries(filter)
.filter(([key]) => !excludeKeys || !excludeKeys.includes(key as keyof R))
.map(([key, value]) => [`${tableName}.${key}`, value])
)
: filter;
void bd.where(processedFilter);
if ($in) {
Object.entries($in).forEach(([key, val]) => {
if (val) {
void bd.whereIn(key as never, val as never);
void bd.whereIn(`${tableName ? `${tableName}.` : ""}${key}`, val as never);
}
});
}
if ($notNull?.length) {
$notNull.forEach((key) => {
void bd.whereNotNull(key as never);
void bd.whereNotNull(`${tableName ? `${tableName}.` : ""}${key as string}`);
});
}
if ($search) {
Object.entries($search).forEach(([key, val]) => {
if (val) {
void bd.whereILike(key as never, val as never);
void bd.whereILike(`${tableName ? `${tableName}.` : ""}${key}`, val as never);
}
});
}
+14
View File
@@ -16,3 +16,17 @@ export const fetchGithubEmails = async (accessToken: string) => {
});
return data;
};
type TGithubUser = {
name?: string;
login: string;
};
export const fetchGithubUser = async (accessToken: string) => {
const { data } = await request.get<TGithubUser>(`${INTEGRATION_GITHUB_API_URL}/user`, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
return data;
};
+4 -4
View File
@@ -15,13 +15,13 @@ export const blockLocalAndPrivateIpAddresses = async (url: string) => {
const validUrl = new URL(url);
const inputHostIps: string[] = [];
if (isIPv4(validUrl.host)) {
inputHostIps.push(validUrl.host);
if (isIPv4(validUrl.hostname)) {
inputHostIps.push(validUrl.hostname);
} else {
if (validUrl.host === "localhost" || validUrl.host === "host.docker.internal") {
if (validUrl.hostname === "localhost" || validUrl.hostname === "host.docker.internal") {
throw new BadRequestError({ message: "Local IPs not allowed as URL" });
}
const resolvedIps = await dns.resolve4(validUrl.host);
const resolvedIps = await dns.resolve4(validUrl.hostname);
inputHostIps.push(...resolvedIps);
}
const isInternalIp = inputHostIps.some((el) => isPrivateIp(el));