-
-
Notifications
You must be signed in to change notification settings - Fork 493
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
121 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,7 +100,11 @@ const createRouters = (tenant: TenantContext) => { | |
systemRoutes(managementRouter, tenant); | ||
subjectTokenRoutes(managementRouter, tenant); | ||
accountCentersRoutes(managementRouter, tenant); | ||
if (EnvSet.values.isDevFeaturesEnabled) { | ||
// TODO: @darcy per our design, we will move related routes to Cloud repo and the routes will be loaded from remote. | ||
Check warning on line 103 in packages/core/src/routes/init.ts
|
||
if ( | ||
(EnvSet.values.isDevFeaturesEnabled && EnvSet.values.isCloud) || | ||
EnvSet.values.isIntegrationTest | ||
) { | ||
samlApplicationRoutes(managementRouter, tenant); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
packages/core/src/saml-applications/libraries/utils.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { addDays } from 'date-fns'; | ||
import forge from 'node-forge'; | ||
|
||
import { generateKeyPairAndCertificate } from './utils.js'; | ||
|
||
describe('generateKeyPairAndCertificate', () => { | ||
it('should generate valid key pair and certificate', async () => { | ||
const result = await generateKeyPairAndCertificate(); | ||
|
||
// Verify private key format | ||
expect(result.privateKey).toContain('-----BEGIN RSA PRIVATE KEY-----'); | ||
expect(result.privateKey).toContain('-----END RSA PRIVATE KEY-----'); | ||
|
||
// Verify certificate format | ||
expect(result.certificate).toContain('-----BEGIN CERTIFICATE-----'); | ||
expect(result.certificate).toContain('-----END CERTIFICATE-----'); | ||
|
||
// Verify expiration date (default 365 days) | ||
const expectedNotAfter = addDays(new Date(), 365); | ||
expect(result.notAfter.getDate()).toBe(expectedNotAfter.getDate()); | ||
expect(result.notAfter.getMonth()).toBe(expectedNotAfter.getMonth()); | ||
expect(result.notAfter.getFullYear()).toBe(expectedNotAfter.getFullYear()); | ||
|
||
// Verify certificate content | ||
const cert = forge.pki.certificateFromPem(result.certificate); | ||
expect(cert.subject.getField('CN').value).toBe('example.com'); | ||
expect(cert.issuer.getField('CN').value).toBe('logto.io'); | ||
expect(cert.issuer.getField('O').value).toBe('Logto'); | ||
expect(cert.issuer.getField('C').value).toBe('US'); | ||
}); | ||
|
||
it('should generate certificate with custom lifespan', async () => { | ||
const customDays = 30; | ||
const result = await generateKeyPairAndCertificate(customDays); | ||
|
||
const expectedNotAfter = addDays(new Date(), customDays); | ||
expect(result.notAfter.getDate()).toBe(expectedNotAfter.getDate()); | ||
expect(result.notAfter.getMonth()).toBe(expectedNotAfter.getMonth()); | ||
expect(result.notAfter.getFullYear()).toBe(expectedNotAfter.getFullYear()); | ||
}); | ||
|
||
it('should generate unique serial numbers for different certificates', async () => { | ||
const result1 = await generateKeyPairAndCertificate(); | ||
const result2 = await generateKeyPairAndCertificate(); | ||
|
||
const cert1 = forge.pki.certificateFromPem(result1.certificate); | ||
const cert2 = forge.pki.certificateFromPem(result2.certificate); | ||
|
||
expect(cert1.serialNumber).not.toBe(cert2.serialNumber); | ||
}); | ||
|
||
it('should generate RSA key pair with 4096 bits', async () => { | ||
const result = await generateKeyPairAndCertificate(); | ||
const privateKey = forge.pki.privateKeyFromPem(result.privateKey); | ||
|
||
// RSA key should be 4096 bits | ||
expect(forge.pki.privateKeyToPem(privateKey).length).toBeGreaterThan(3000); // A 4096-bit RSA private key in PEM format is typically longer than 3000 characters | ||
}); | ||
}); |
95 changes: 0 additions & 95 deletions
95
packages/core/src/saml-applications/routes/index.openapi.json
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,42 @@ | ||
import { | ||
type SamlApplicationResponse, | ||
type SamlApplicationSecret, | ||
type Application, | ||
type SamlApplicationConfig, | ||
type SamlAcsUrl, | ||
BindingType, | ||
} from '@logto/schemas'; | ||
|
||
import RequestError from '#src/errors/RequestError/index.js'; | ||
import assertThat from '#src/utils/assert-that.js'; | ||
|
||
/** | ||
* According to the design, a SAML app will be associated with multiple records from various tables. | ||
* Therefore, when complete SAML app data is required, it is necessary to retrieve multiple related records and assemble them into a comprehensive SAML app dataset. This dataset includes: | ||
* - A record from the `applications` table with a `type` of `SAML` | ||
* - A record from the `saml_application_configs` table | ||
*/ | ||
export const ensembleSamlApplication = ({ | ||
application, | ||
samlConfig, | ||
samlSecret, | ||
}: { | ||
application: Application; | ||
samlConfig: Pick<SamlApplicationConfig, 'attributeMapping' | 'entityId' | 'acsUrl'>; | ||
samlSecret?: SamlApplicationSecret | SamlApplicationSecret[]; | ||
}): SamlApplicationResponse => { | ||
return { | ||
...application, | ||
...samlConfig, | ||
secrets: samlSecret ? (Array.isArray(samlSecret) ? samlSecret : [samlSecret]) : [], | ||
}; | ||
}; | ||
|
||
/** | ||
* Only HTTP-POST binding is supported for receiving SAML assertions at the moment. | ||
*/ | ||
export const validateAcsUrl = (acsUrl: SamlAcsUrl) => { | ||
assertThat( | ||
acsUrl.binding === BindingType.POST, | ||
new RequestError({ | ||
code: 'application.saml.acs_url_binding_not_supported', | ||
status: 422, | ||
}) | ||
); | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters