Compare commits

..

3 Commits

Author SHA1 Message Date
Owen
874794c996 Clean email 2026-02-18 14:07:50 -08:00
Owen
5e37c4e85f Resolve potential issues with processing roleIds 2026-02-18 13:55:04 -08:00
Owen
4e7eac368f Uniform ne check on niceId and dont reject clients 2026-02-18 11:56:01 -08:00
13 changed files with 133 additions and 64 deletions

67
package-lock.json generated
View File

@@ -124,7 +124,7 @@
"@types/js-yaml": "4.0.9",
"@types/jsonwebtoken": "9.0.10",
"@types/node": "25.2.3",
"@types/nodemailer": "7.0.10",
"@types/nodemailer": "7.0.9",
"@types/nprogress": "0.2.3",
"@types/pg": "8.16.0",
"@types/react": "19.2.14",
@@ -1086,6 +1086,7 @@
"integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.2",
@@ -2817,6 +2818,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -2839,6 +2841,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -2861,6 +2864,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2877,6 +2881,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2893,6 +2898,7 @@
"cpu": [
"arm"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2909,6 +2915,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2925,6 +2932,7 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2941,6 +2949,7 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2957,6 +2966,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2973,6 +2983,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -2989,6 +3000,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -3005,6 +3017,7 @@
"cpu": [
"arm"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3027,6 +3040,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3049,6 +3063,7 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3071,6 +3086,7 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3093,6 +3109,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3115,6 +3132,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3137,6 +3155,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -3159,6 +3178,7 @@
"cpu": [
"wasm32"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
"dependencies": {
@@ -3178,6 +3198,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -3197,6 +3218,7 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -3216,6 +3238,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -3497,6 +3520,7 @@
"integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": "^14.21.3 || >=16"
},
@@ -7926,6 +7950,7 @@
"resolved": "https://registry.npmjs.org/@react-email/text/-/text-0.1.6.tgz",
"integrity": "sha512-TYqkioRS45wTR5il3dYk/SbUjjEdhSwh9BtRNB99qNH1pXAwA45H7rAuxehiu8iJQJH0IyIr+6n62gBz9ezmsw==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=20.0.0"
},
@@ -9344,6 +9369,7 @@
"version": "5.90.21",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz",
"integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==",
"peer": true,
"dependencies": {
"@tanstack/query-core": "5.90.20"
},
@@ -9459,6 +9485,7 @@
"integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/node": "*"
}
@@ -9799,6 +9826,7 @@
"integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^5.0.0",
@@ -9893,14 +9921,15 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz",
"integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==",
"devOptional": true,
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
},
"node_modules/@types/nodemailer": {
"version": "7.0.10",
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.10.tgz",
"integrity": "sha512-tP+9WggTFN22Zxh0XFyst7239H0qwiRCogsk7v9aQS79sYAJY+WEbTHbNYcxUMaalHKmsNpxmoTe35hBEMMd6g==",
"version": "7.0.9",
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-7.0.9.tgz",
"integrity": "sha512-vI8oF1M+8JvQhsId0Pc38BdUP2evenIIys7c7p+9OZXSPOH5c1dyINP1jT8xQ2xPuBUXmIC87s+91IZMDjH8Ow==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9920,6 +9949,7 @@
"integrity": "sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/node": "*",
"pg-protocol": "*",
@@ -9945,6 +9975,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"devOptional": true,
"peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -9955,6 +9986,7 @@
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"devOptional": true,
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -10041,8 +10073,7 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT",
"optional": true,
"peer": true
"optional": true
},
"node_modules/@types/ws": {
"version": "8.18.1",
@@ -10113,6 +10144,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz",
"integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==",
"dev": true,
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.55.0",
"@typescript-eslint/types": "8.55.0",
@@ -10602,6 +10634,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -11066,6 +11099,7 @@
"integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.26.0"
}
@@ -11132,6 +11166,7 @@
"integrity": "sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==",
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"dependencies": {
"bindings": "^1.5.0",
"prebuild-install": "^7.1.1"
@@ -11258,6 +11293,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -12211,6 +12247,7 @@
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"license": "ISC",
"peer": true,
"engines": {
"node": ">=12"
}
@@ -12651,7 +12688,6 @@
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz",
"integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==",
"license": "(MPL-2.0 OR Apache-2.0)",
"peer": true,
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
@@ -13765,6 +13801,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -13863,6 +13900,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -14048,6 +14086,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -14367,6 +14406,7 @@
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
"peer": true,
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
@@ -16876,7 +16916,6 @@
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz",
"integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==",
"license": "MIT",
"peer": true,
"dependencies": {
"dompurify": "3.2.7",
"marked": "14.0.0"
@@ -16887,7 +16926,6 @@
"resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz",
"integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==",
"license": "MIT",
"peer": true,
"bin": {
"marked": "bin/marked.js"
},
@@ -16975,6 +17013,7 @@
"version": "15.5.12",
"resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz",
"integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==",
"peer": true,
"dependencies": {
"@next/env": "15.5.12",
"@swc/helpers": "0.5.15",
@@ -17909,6 +17948,7 @@
"resolved": "https://registry.npmjs.org/pg/-/pg-8.18.0.tgz",
"integrity": "sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"pg-connection-string": "^2.11.0",
"pg-pool": "^3.11.0",
@@ -18403,6 +18443,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -18432,6 +18473,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -19248,6 +19290,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz",
"integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -20717,7 +20760,8 @@
"version": "4.1.18",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
"integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/tapable": {
"version": "2.3.0",
@@ -21191,6 +21235,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -21617,6 +21662,7 @@
"resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz",
"integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@colors/colors": "^1.6.0",
"@dabh/diagnostics": "^2.0.8",
@@ -21823,6 +21869,7 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}

View File

@@ -147,7 +147,7 @@
"@types/js-yaml": "4.0.9",
"@types/jsonwebtoken": "9.0.10",
"@types/node": "25.2.3",
"@types/nodemailer": "7.0.10",
"@types/nodemailer": "7.0.9",
"@types/nprogress": "0.2.3",
"@types/pg": "8.16.0",
"@types/react": "19.2.14",

View File

@@ -46,6 +46,8 @@ export class UsageService {
return null;
}
let orgIdToUse = await this.getBillingOrg(orgId, transaction);
// Truncate value to 11 decimal places
value = this.truncateValue(value);
@@ -57,7 +59,6 @@ export class UsageService {
try {
let usage;
if (transaction) {
const orgIdToUse = await this.getBillingOrg(orgId, transaction);
usage = await this.internalAddUsage(
orgIdToUse,
featureId,
@@ -66,7 +67,6 @@ export class UsageService {
);
} else {
await db.transaction(async (trx) => {
const orgIdToUse = await this.getBillingOrg(orgId, trx);
usage = await this.internalAddUsage(
orgIdToUse,
featureId,
@@ -92,7 +92,7 @@ export class UsageService {
const delay = baseDelay + jitter;
logger.warn(
`Deadlock detected for ${orgId}/${featureId}, retrying attempt ${attempt}/${maxRetries} after ${delay.toFixed(0)}ms`
`Deadlock detected for ${orgIdToUse}/${featureId}, retrying attempt ${attempt}/${maxRetries} after ${delay.toFixed(0)}ms`
);
await new Promise((resolve) => setTimeout(resolve, delay));
@@ -100,7 +100,7 @@ export class UsageService {
}
logger.error(
`Failed to add usage for ${orgId}/${featureId} after ${attempt} attempts:`,
`Failed to add usage for ${orgIdToUse}/${featureId} after ${attempt} attempts:`,
error
);
break;
@@ -169,7 +169,7 @@ export class UsageService {
return;
}
const orgIdToUse = await this.getBillingOrg(orgId);
let orgIdToUse = await this.getBillingOrg(orgId);
try {
// Truncate value to 11 decimal places if provided
@@ -227,7 +227,7 @@ export class UsageService {
orgId: string,
featureId: FeatureId
): Promise<string | null> {
const orgIdToUse = await this.getBillingOrg(orgId);
let orgIdToUse = await this.getBillingOrg(orgId);
const cacheKey = `customer_${orgIdToUse}_${featureId}`;
const cached = cache.get<string>(cacheKey);
@@ -274,7 +274,7 @@ export class UsageService {
return null;
}
const orgIdToUse = await this.getBillingOrg(orgId, trx);
let orgIdToUse = await this.getBillingOrg(orgId, trx);
const usageId = `${orgIdToUse}-${featureId}`;
@@ -382,7 +382,7 @@ export class UsageService {
return false;
}
const orgIdToUse = await this.getBillingOrg(orgId, trx);
let orgIdToUse = await this.getBillingOrg(orgId, trx);
// This method should check the current usage against the limits set for the organization
// and kick out all of the sites on the org

View File

@@ -23,9 +23,14 @@ export async function verifyApiKeyRoleAccess(
);
}
const { roleIds } = req.body;
const allRoleIds =
roleIds || (isNaN(singleRoleId) ? [] : [singleRoleId]);
let allRoleIds: number[] = [];
if (!isNaN(singleRoleId)) {
// If roleId is provided in URL params, query params, or body (single), use it exclusively
allRoleIds = [singleRoleId];
} else if (req.body?.roleIds) {
// Only use body.roleIds if no single roleId was provided
allRoleIds = req.body.roleIds;
}
if (allRoleIds.length === 0) {
return next();

View File

@@ -23,8 +23,14 @@ export async function verifyRoleAccess(
);
}
const roleIds = req.body?.roleIds;
const allRoleIds = roleIds || (isNaN(singleRoleId) ? [] : [singleRoleId]);
let allRoleIds: number[] = [];
if (!isNaN(singleRoleId)) {
// If roleId is provided in URL params, query params, or body (single), use it exclusively
allRoleIds = [singleRoleId];
} else if (req.body?.roleIds) {
// Only use body.roleIds if no single roleId was provided
allRoleIds = req.body.roleIds;
}
if (allRoleIds.length === 0) {
return next();

View File

@@ -78,8 +78,7 @@ export async function getOrgTierData(
if (
subscription.type === "tier1" ||
subscription.type === "tier2" ||
subscription.type === "tier3" ||
subscription.type === "enterprise"
subscription.type === "tier3"
) {
tier = subscription.type;
active = true;

View File

@@ -139,7 +139,7 @@ export async function signSshKey(
if (!userOrg.pamUsername) {
if (req.user?.email) {
// Extract username from email (first part before @)
usernameToUse = req.user?.email.split("@")[0];
usernameToUse = req.user?.email.split("@")[0].replace(/[^a-zA-Z0-9_-]/g, "");
if (!usernameToUse) {
return next(
createHttpError(

View File

@@ -6,7 +6,7 @@ import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { eq, and } from "drizzle-orm";
import { eq, and, ne } from "drizzle-orm";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
@@ -93,7 +93,8 @@ export async function updateClient(
.where(
and(
eq(clients.niceId, niceId),
eq(clients.orgId, clients.orgId)
eq(clients.orgId, clients.orgId),
ne(clients.clientId, clientId)
)
)
.limit(1);

View File

@@ -197,6 +197,7 @@ export async function updateSiteBandwidth(
usageService
.checkLimitSet(
orgId,
FeatureId.EGRESS_DATA_MB,
bandwidthUsage
)

View File

@@ -9,7 +9,7 @@ import {
Resource,
resources
} from "@server/db";
import { eq, and } from "drizzle-orm";
import { eq, and, ne } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
@@ -33,7 +33,15 @@ const updateResourceParamsSchema = z.strictObject({
const updateHttpResourceBodySchema = z
.strictObject({
name: z.string().min(1).max(255).optional(),
niceId: z.string().min(1).max(255).regex(/^[a-zA-Z0-9-]+$/, "niceId can only contain letters, numbers, and dashes").optional(),
niceId: z
.string()
.min(1)
.max(255)
.regex(
/^[a-zA-Z0-9-]+$/,
"niceId can only contain letters, numbers, and dashes"
)
.optional(),
subdomain: subdomainSchema.nullable().optional(),
ssl: z.boolean().optional(),
sso: z.boolean().optional(),
@@ -248,14 +256,13 @@ async function updateHttpResource(
.where(
and(
eq(resources.niceId, updateData.niceId),
eq(resources.orgId, resource.orgId)
eq(resources.orgId, resource.orgId),
ne(resources.resourceId, resource.resourceId) // exclude the current resource from the search
)
);
)
.limit(1);
if (
existingResource &&
existingResource.resourceId !== resource.resourceId
) {
if (existingResource) {
return next(
createHttpError(
HttpCode.CONFLICT,
@@ -343,7 +350,10 @@ async function updateHttpResource(
headers = null;
}
const isLicensed = await isLicensedOrSubscribed(resource.orgId, tierMatrix.maintencePage);
const isLicensed = await isLicensedOrSubscribed(
resource.orgId,
tierMatrix.maintencePage
);
if (!isLicensed) {
updateData.maintenanceModeEnabled = undefined;
updateData.maintenanceModeType = undefined;

View File

@@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { sites } from "@server/db";
import { eq, and } from "drizzle-orm";
import { eq, and, ne } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
@@ -19,8 +19,8 @@ const updateSiteBodySchema = z
.strictObject({
name: z.string().min(1).max(255).optional(),
niceId: z.string().min(1).max(255).optional(),
dockerSocketEnabled: z.boolean().optional(),
remoteSubnets: z.string().optional()
dockerSocketEnabled: z.boolean().optional()
// remoteSubnets: z.string().optional()
// subdomain: z
// .string()
// .min(1)
@@ -86,18 +86,19 @@ export async function updateSite(
// if niceId is provided, check if it's already in use by another site
if (updateData.niceId) {
const existingSite = await db
const [existingSite] = await db
.select()
.from(sites)
.where(
and(
eq(sites.niceId, updateData.niceId),
eq(sites.orgId, sites.orgId)
eq(sites.orgId, sites.orgId),
ne(sites.siteId, siteId)
)
)
.limit(1);
if (existingSite.length > 0 && existingSite[0].siteId !== siteId) {
if (existingSite) {
return next(
createHttpError(
HttpCode.CONFLICT,
@@ -107,22 +108,22 @@ export async function updateSite(
}
}
// if remoteSubnets is provided, ensure it's a valid comma-separated list of cidrs
if (updateData.remoteSubnets) {
const subnets = updateData.remoteSubnets
.split(",")
.map((s) => s.trim());
for (const subnet of subnets) {
if (!isValidCIDR(subnet)) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
`Invalid CIDR format: ${subnet}`
)
);
}
}
}
// // if remoteSubnets is provided, ensure it's a valid comma-separated list of cidrs
// if (updateData.remoteSubnets) {
// const subnets = updateData.remoteSubnets
// .split(",")
// .map((s) => s.trim());
// for (const subnet of subnets) {
// if (!isValidCIDR(subnet)) {
// return next(
// createHttpError(
// HttpCode.BAD_REQUEST,
// `Invalid CIDR format: ${subnet}`
// )
// );
// }
// }
// }
const updatedSite = await db
.update(sites)

View File

@@ -20,7 +20,7 @@ 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 == "tier1" || subRes.data.data.tier == "tier2" || subRes.data.data.tier == "tier3") &&
subRes.data.data.active;
} catch {}
}

View File

@@ -42,8 +42,7 @@ export function SubscriptionStatusProvider({
if (
subscription.type == "tier1" ||
subscription.type == "tier2" ||
subscription.type == "tier3" ||
subscription.type == "enterprise"
subscription.type == "tier3"
) {
return {
tier: subscription.type,
@@ -62,7 +61,7 @@ export function SubscriptionStatusProvider({
const isSubscribed = () => {
const { tier, active } = getTier();
return (
(tier == "tier1" || tier == "tier2" || tier == "tier3" || tier == "enterprise") &&
(tier == "tier1" || tier == "tier2" || tier == "tier3") &&
active
);
};