diff --git a/data/idp-metadata.xml b/data/idp-metadata.xml
deleted file mode 100644
index 43fbf7a..0000000
--- a/data/idp-metadata.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
- {{idp_certificate}}
-
-
-
-
-
- urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
-
-
-
-
-
diff --git a/utils/idp.ts b/utils/idp.ts
index 69ec426..0aba1f9 100644
--- a/utils/idp.ts
+++ b/utils/idp.ts
@@ -1,5 +1,4 @@
-import { promises as fs } from 'fs';
-import path from 'path';
+import xmlbuilder from 'xmlbuilder';
import { stripCertHeaderAndFooter } from './certificate';
const createIdPMetadataXML = async ({
@@ -11,14 +10,45 @@ const createIdPMetadataXML = async ({
idpSsoUrl: string;
certificate: string;
}): Promise => {
- const xmlPath = path.join('data', 'idp-metadata.xml');
- const xml = await fs.readFile(xmlPath, 'utf8');
certificate = stripCertHeaderAndFooter(certificate);
- return xml
- .replace('{{idp_entity_id}}', idpEntityId)
- .replace('{{idp_certificate}}', certificate)
- .replace(/{{idp_sso_url}}/g, idpSsoUrl);
+ const nodes = {
+ EntityDescriptor: {
+ '@xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata',
+ '@entityID': idpEntityId,
+ '@validUntil': '2026-06-22T18:39:53.000Z',
+ IDPSSODescriptor: {
+ '@WantAuthnRequestsSigned': false,
+ '@protocolSupportEnumeration': 'urn:oasis:names:tc:SAML:2.0:protocol',
+ KeyDescriptor: {
+ '@use': 'signing',
+ KeyInfo: {
+ '@xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#',
+ X509Data: {
+ X509Certificate: {
+ '#text': certificate,
+ },
+ },
+ },
+ },
+ NameIDFormat: {
+ '#text': 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
+ },
+ SingleSignOnService: [
+ {
+ '@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
+ '@Location': idpSsoUrl,
+ },
+ {
+ '@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
+ '@Location': idpSsoUrl,
+ },
+ ],
+ },
+ },
+ };
+
+ return xmlbuilder.create(nodes, { encoding: 'UTF-8', standalone: false }).end();
};
export { createIdPMetadataXML };