0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

refactor(core): add SAML app quota guard (#6941)

This commit is contained in:
Darcy Ye 2025-01-15 10:00:16 +08:00 committed by GitHub
parent c41ecc40df
commit 6541749f9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 36 additions and 6 deletions

View file

@ -27,7 +27,7 @@
"devDependencies": {
"@fontsource/roboto-mono": "^5.0.0",
"@jest/types": "^29.5.0",
"@logto/cloud": "0.2.5-aac51e9",
"@logto/cloud": "0.2.5-c98a257",
"@logto/connector-kit": "workspace:^4.1.0",
"@logto/core-kit": "workspace:^2.5.2",
"@logto/language-kit": "workspace:^1.1.0",

View file

@ -29,6 +29,7 @@ export const skuQuotaItemPhrasesMap: Record<
subjectTokenEnabled: 'impersonation_enabled.name',
bringYourUiEnabled: 'bring_your_ui_enabled.name',
idpInitiatedSsoEnabled: 'idp_initiated_sso_enabled.name',
samlApplicationsLimit: 'saml_applications_limit.name',
};
export const skuQuotaItemUnlimitedPhrasesMap: Record<
@ -57,6 +58,7 @@ export const skuQuotaItemUnlimitedPhrasesMap: Record<
subjectTokenEnabled: 'impersonation_enabled.unlimited',
bringYourUiEnabled: 'bring_your_ui_enabled.unlimited',
idpInitiatedSsoEnabled: 'idp_initiated_sso_enabled.unlimited',
samlApplicationsLimit: 'saml_applications_limit.unlimited',
};
export const skuQuotaItemLimitedPhrasesMap: Record<
@ -85,6 +87,7 @@ export const skuQuotaItemLimitedPhrasesMap: Record<
subjectTokenEnabled: 'impersonation_enabled.limited',
bringYourUiEnabled: 'bring_your_ui_enabled.limited',
idpInitiatedSsoEnabled: 'idp_initiated_sso_enabled.limited',
samlApplicationsLimit: 'saml_applications_limit.limited',
};
export const skuQuotaItemNotEligiblePhrasesMap: Record<
@ -113,5 +116,6 @@ export const skuQuotaItemNotEligiblePhrasesMap: Record<
subjectTokenEnabled: 'impersonation_enabled.not_eligible',
bringYourUiEnabled: 'bring_your_ui_enabled.not_eligible',
idpInitiatedSsoEnabled: 'idp_initiated_sso_enabled.not_eligible',
samlApplicationsLimit: 'saml_applications_limit.not_eligible',
};
/* === for new pricing model === */

View file

@ -109,6 +109,7 @@ export const defaultSubscriptionQuota: NewSubscriptionQuota = {
subjectTokenEnabled: false,
bringYourUiEnabled: false,
idpInitiatedSsoEnabled: false,
samlApplicationsLimit: 0,
};
export const defaultSubscriptionUsage: NewSubscriptionCountBasedUsage = {
@ -130,6 +131,7 @@ export const defaultSubscriptionUsage: NewSubscriptionCountBasedUsage = {
subjectTokenEnabled: false,
bringYourUiEnabled: false,
idpInitiatedSsoEnabled: false,
samlApplicationsLimit: 0,
};
const getAdminTenantEndpoint = () => {

View file

@ -99,7 +99,7 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@logto/cloud": "0.2.5-aac51e9",
"@logto/cloud": "0.2.5-c98a257",
"@silverhand/eslint-config": "6.0.1",
"@silverhand/ts-config": "6.0.0",
"@types/adm-zip": "^0.5.5",

View file

@ -36,6 +36,7 @@ export const mockQuota = {
subjectTokenEnabled: false,
bringYourUiEnabled: false,
idpInitiatedSsoEnabled: false,
samlApplicationsLimit: 0,
};
export const mockSubscriptionData: Subscription = {

View file

@ -13,6 +13,7 @@ import { z } from 'zod';
import { EnvSet } from '#src/env-set/index.js';
import RequestError from '#src/errors/RequestError/index.js';
import koaGuard from '#src/middleware/koa-guard.js';
import { koaQuotaGuard } from '#src/middleware/koa-quota-guard.js';
import { buildOidcClientMetadata } from '#src/oidc/utils.js';
import { generateInternalSecret } from '#src/routes/applications/application-secret.js';
import type { ManagementApiRouter, RouterInitArgs } from '#src/routes/types.js';
@ -45,10 +46,12 @@ export default function samlApplicationRoutes<T extends ManagementApiRouter>(
findSamlApplicationById,
updateSamlApplicationById,
},
quota,
} = libraries;
router.post(
'/saml-applications',
koaQuotaGuard({ key: 'samlApplicationsLimit', quota }),
koaGuard({
body: samlApplicationCreateGuard,
response: samlApplicationResponseGuard,
@ -178,6 +181,7 @@ export default function samlApplicationRoutes<T extends ManagementApiRouter>(
router.post(
'/saml-applications/:id/secrets',
koaQuotaGuard({ key: 'samlApplicationsLimit', quota }),
koaGuard({
params: z.object({ id: z.string() }),
// The life span of the SAML app secret is in years (at least 1 year), and for security concern, secrets which never expire are not recommended.

View file

@ -99,6 +99,7 @@ const logtoSkuQuotaGuard = z.object({
organizationsEnabled: z.boolean(),
organizationsLimit: z.number().nullable(),
idpInitiatedSsoEnabled: z.boolean(),
samlApplicationsLimit: z.number().nullable(),
}) satisfies ToZodObject<SubscriptionQuota>;
/**

View file

@ -177,6 +177,13 @@ const quota_item = {
unlimited: 'IDP-initiated SSO',
not_eligible: 'IDP-initiated SSO not allowed',
},
saml_applications_limit: {
name: 'SAML applications',
limited: '{{count, number}} SAML application',
limited_other: '{{count, number}} SAML applications',
unlimited: 'Unlimited SAML applications',
not_eligible: 'Remove your SAML applications',
},
};
export default Object.freeze(quota_item);

19
pnpm-lock.yaml generated
View file

@ -2858,8 +2858,8 @@ importers:
specifier: ^29.5.0
version: 29.5.0
'@logto/cloud':
specifier: 0.2.5-aac51e9
version: 0.2.5-aac51e9(zod@3.23.8)
specifier: 0.2.5-c98a257
version: 0.2.5-c98a257(zod@3.23.8)
'@logto/connector-kit':
specifier: workspace:^4.1.0
version: link:../toolkit/connector-kit
@ -3354,8 +3354,8 @@ importers:
version: 3.23.8
devDependencies:
'@logto/cloud':
specifier: 0.2.5-aac51e9
version: 0.2.5-aac51e9(zod@3.23.8)
specifier: 0.2.5-c98a257
version: 0.2.5-c98a257(zod@3.23.8)
'@silverhand/eslint-config':
specifier: 6.0.1
version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.5.3)
@ -6206,6 +6206,10 @@ packages:
resolution: {integrity: sha512-p/9u33xBFIuh6NRFO5D/G2rsvmZJAdnjjB6n8RxlMp34XHBuRRmiuB/KadKFQmUkPVJhDOo5hs9dgdd28ClQIA==}
engines: {node: ^20.9.0}
'@logto/cloud@0.2.5-c98a257':
resolution: {integrity: sha512-/xXcTtYq3aCJUEADIRlbKZJKL345cHOvimSjq/DExYJXm7PkB3iaJAwlXRcmESkPxLom1o10WDQtuV9dPNVmzA==}
engines: {node: ^20.9.0}
'@logto/js@4.1.4':
resolution: {integrity: sha512-6twud1nFBQmj89/aflzej6yD1QwXfPiYmRtyYuN4a7O9OaaW3X/kJBVwjKUn5NC9IUt+rd+jXsI3QJXENfaLAw==}
@ -16503,6 +16507,13 @@ snapshots:
transitivePeerDependencies:
- zod
'@logto/cloud@0.2.5-c98a257(zod@3.23.8)':
dependencies:
'@silverhand/essentials': 2.9.2
'@withtyped/server': 0.14.0(zod@3.23.8)
transitivePeerDependencies:
- zod
'@logto/js@4.1.4':
dependencies:
'@silverhand/essentials': 2.9.2