Compare commits

...

6 Commits

Author SHA1 Message Date
Daniel Hougaard
c4c8e121f0 Update OauthCallbackPage.tsx 2025-07-30 21:03:36 +04:00
Scott Wilson
b9dd565926 Merge pull request #4273 from Infisical/improve-initial-app-loading-ui
improvement(frontend): make login/org selection loading screens consistent
2025-07-30 09:11:33 -07:00
Daniel Hougaard
136b0bdcb5 Merge pull request #4275 from Infisical/daniel/update-passport-saml
fix: update passport saml
2025-07-30 18:14:21 +04:00
Daniel Hougaard
7266d1f310 fix: update passport saml 2025-07-30 17:43:57 +04:00
carlosmonastyrski
9c6ec807cb Merge pull request #4212 from Infisical/feat/blockLastPaymentMethodDelete
Prevent users from deleting the last payment method attached to the org
2025-07-30 09:59:50 -03:00
Carlos Monastyrski
b4ed1fa96a Prevent users from deleting the last payment method attached to the org 2025-07-21 21:17:36 -03:00
5 changed files with 58 additions and 37 deletions

View File

@@ -7,7 +7,6 @@
"": {
"name": "backend",
"version": "1.0.0",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"@aws-sdk/client-elasticache": "^3.637.0",
@@ -34,7 +33,7 @@
"@gitbeaker/rest": "^42.5.0",
"@google-cloud/kms": "^4.5.0",
"@infisical/quic": "^1.0.8",
"@node-saml/passport-saml": "^5.0.1",
"@node-saml/passport-saml": "^5.1.0",
"@octokit/auth-app": "^7.1.1",
"@octokit/core": "^5.2.1",
"@octokit/plugin-paginate-graphql": "^4.0.1",
@@ -9574,20 +9573,20 @@
}
},
"node_modules/@node-saml/node-saml": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-5.0.1.tgz",
"integrity": "sha512-YQzFPEC+CnsfO9AFYnwfYZKIzOLx3kITaC1HrjHVLTo6hxcQhc+LgHODOMvW4VCV95Gwrz1MshRUWCPzkDqmnA==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-5.1.0.tgz",
"integrity": "sha512-t3cJnZ4aC7HhPZ6MGylGZULvUtBOZ6FzuUndaHGXjmIZHXnLfC/7L8a57O9Q9V7AxJGKAiRM5zu2wNm9EsvQpw==",
"license": "MIT",
"dependencies": {
"@types/debug": "^4.1.12",
"@types/qs": "^6.9.11",
"@types/qs": "^6.9.18",
"@types/xml-encryption": "^1.2.4",
"@types/xml2js": "^0.4.14",
"@xmldom/is-dom-node": "^1.0.1",
"@xmldom/xmldom": "^0.8.10",
"debug": "^4.3.4",
"xml-crypto": "^6.0.1",
"xml-encryption": "^3.0.2",
"debug": "^4.4.0",
"xml-crypto": "^6.1.2",
"xml-encryption": "^3.1.0",
"xml2js": "^0.6.2",
"xmlbuilder": "^15.1.1",
"xpath": "^0.0.34"
@@ -9597,9 +9596,9 @@
}
},
"node_modules/@node-saml/node-saml/node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -9636,14 +9635,14 @@
}
},
"node_modules/@node-saml/passport-saml": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@node-saml/passport-saml/-/passport-saml-5.0.1.tgz",
"integrity": "sha512-fMztg3zfSnjLEgxvpl6HaDMNeh0xeQX4QHiF9e2Lsie2dc4qFE37XYbQZhVmn8XJ2awPpSWLQ736UskYgGU8lQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@node-saml/passport-saml/-/passport-saml-5.1.0.tgz",
"integrity": "sha512-pBm+iFjv9eihcgeJuSUs4c0AuX1QEFdHwP8w1iaWCfDzXdeWZxUBU5HT2bY2S4dvNutcy+A9hYsH7ZLBGtgwDg==",
"license": "MIT",
"dependencies": {
"@node-saml/node-saml": "^5.0.1",
"@types/express": "^4.17.21",
"@types/passport": "^1.0.16",
"@node-saml/node-saml": "^5.1.0",
"@types/express": "^4.17.23",
"@types/passport": "^1.0.17",
"@types/passport-strategy": "^0.2.38",
"passport": "^0.7.0",
"passport-strategy": "^1.0.0"
@@ -13351,9 +13350,10 @@
"license": "MIT"
},
"node_modules/@types/express": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz",
"integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==",
"license": "MIT",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -13523,9 +13523,10 @@
}
},
"node_modules/@types/passport": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz",
"integrity": "sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==",
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.17.tgz",
"integrity": "sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==",
"license": "MIT",
"dependencies": {
"@types/express": "*"
}
@@ -31953,9 +31954,9 @@
"license": "MIT"
},
"node_modules/xml-crypto": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-6.0.1.tgz",
"integrity": "sha512-v05aU7NS03z4jlZ0iZGRFeZsuKO1UfEbbYiaeRMiATBFs6Jq9+wqKquEMTn4UTrYZ9iGD8yz3KT4L9o2iF682w==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-6.1.2.tgz",
"integrity": "sha512-leBOVQdVi8FvPJrMYoum7Ici9qyxfE4kVi+AkpUoYCSXaQF4IlBm1cneTK9oAxR61LpYxTx7lNcsnBIeRpGW2w==",
"license": "MIT",
"dependencies": {
"@xmldom/is-dom-node": "^1.0.1",

View File

@@ -153,7 +153,7 @@
"@gitbeaker/rest": "^42.5.0",
"@google-cloud/kms": "^4.5.0",
"@infisical/quic": "^1.0.8",
"@node-saml/passport-saml": "^5.0.1",
"@node-saml/passport-saml": "^5.1.0",
"@octokit/auth-app": "^7.1.1",
"@octokit/core": "^5.2.1",
"@octokit/plugin-paginate-graphql": "^4.0.1",

View File

@@ -5,13 +5,14 @@
// TODO(akhilmhdh): With tony find out the api structure and fill it here
import { ForbiddenError } from "@casl/ability";
import { AxiosError } from "axios";
import { CronJob } from "cron";
import { Knex } from "knex";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { verifyOfflineLicense } from "@app/lib/crypto";
import { NotFoundError } from "@app/lib/errors";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { TIdentityOrgDALFactory } from "@app/services/identity/identity-org-dal";
import { TOrgDALFactory } from "@app/services/org/org-dal";
@@ -603,10 +604,22 @@ export const licenseServiceFactory = ({
});
}
const { data } = await licenseServerCloudApi.request.delete(
`/api/license-server/v1/customers/${organization.customerId}/billing-details/payment-methods/${pmtMethodId}`
);
return data;
try {
const { data } = await licenseServerCloudApi.request.delete(
`/api/license-server/v1/customers/${organization.customerId}/billing-details/payment-methods/${pmtMethodId}`
);
return data;
} catch (error) {
if (error instanceof AxiosError) {
throw new BadRequestError({
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
message: `Failed to remove payment method: ${error.response?.data?.message}`
});
}
throw new BadRequestError({
message: "Unable to remove payment method"
});
}
};
const getOrgTaxIds = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgTaxIdDTO) => {

View File

@@ -408,7 +408,7 @@ export const OAuthCallbackPage = () => {
credentials: {
code: code as string,
installationId: installationId as string,
host: credentials.host
...(credentials?.host && { host: credentials.host })
},
gatewayId
}
@@ -416,7 +416,7 @@ export const OAuthCallbackPage = () => {
connectionId,
credentials: {
code: code as string,
host: credentials.host
...(credentials?.host && { host: credentials.host })
},
gatewayId
})
@@ -432,7 +432,7 @@ export const OAuthCallbackPage = () => {
credentials: {
code: code as string,
installationId: installationId as string,
host: credentials.host
...(credentials?.host && { host: credentials.host })
},
gatewayId
}
@@ -440,7 +440,7 @@ export const OAuthCallbackPage = () => {
method: GitHubConnectionMethod.OAuth,
credentials: {
code: code as string,
host: credentials.host
...(credentials?.host && { host: credentials.host })
},
gatewayId
})

View File

@@ -32,6 +32,13 @@ export const PmtMethodsTable = () => {
const handleDeletePmtMethodBtnClick = async () => {
if (!currentOrg?.id || !pmtMethodToRemove) return;
if (data?.length === 1) {
createNotification({
type: "error",
text: "You must have at least one payment method"
});
return;
}
try {
await deleteOrgPmtMethod.mutateAsync({
organizationId: currentOrg.id,