diff --git a/package-lock.json b/package-lock.json index f9ff3e4..fca5434 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "next": "12.0.7", "react": "17.0.2", "react-dom": "17.0.2", - "xmlbuilder2": "^3.0.2" + "xmlbuilder": "^15.1.1" }, "devDependencies": { "@types/node": "17.0.8", @@ -1120,50 +1120,6 @@ "node": ">= 8" } }, - "node_modules/@oozcitak/dom": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz", - "integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/url": "1.0.4", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/@oozcitak/infra": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", - "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", - "dependencies": { - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@oozcitak/url": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", - "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/@oozcitak/util": { - "version": "8.3.8", - "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", - "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==", - "engines": { - "node": ">=8.0" - } - }, "node_modules/@prisma/client": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.7.0.tgz", @@ -3091,18 +3047,6 @@ "node": ">=0.4.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -5359,11 +5303,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, "node_modules/stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", @@ -6032,39 +5971,12 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/xmlbuilder2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.0.2.tgz", - "integrity": "sha512-h4MUawGY21CTdhV4xm3DG9dgsqyhDkZvVJBx88beqX8wJs3VgyGQgAn5VreHuae6unTQxh115aMK5InCVmOIKw==", - "dependencies": { - "@oozcitak/dom": "1.15.10", - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8", - "@types/node": "*", - "js-yaml": "3.14.0" - }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "engines": { - "node": ">=12.0" - } - }, - "node_modules/xmlbuilder2/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/xmlbuilder2/node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "node": ">=8.0" } }, "node_modules/xtend": { @@ -6887,38 +6799,6 @@ "fastq": "^1.6.0" } }, - "@oozcitak/dom": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz", - "integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==", - "requires": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/url": "1.0.4", - "@oozcitak/util": "8.3.8" - } - }, - "@oozcitak/infra": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", - "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", - "requires": { - "@oozcitak/util": "8.3.8" - } - }, - "@oozcitak/url": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", - "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", - "requires": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8" - } - }, - "@oozcitak/util": { - "version": "8.3.8", - "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", - "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==" - }, "@prisma/client": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-3.7.0.tgz", @@ -8399,11 +8279,6 @@ } } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -10014,11 +9889,6 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==" }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, "stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", @@ -10533,36 +10403,10 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "xmlbuilder2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.0.2.tgz", - "integrity": "sha512-h4MUawGY21CTdhV4xm3DG9dgsqyhDkZvVJBx88beqX8wJs3VgyGQgAn5VreHuae6unTQxh115aMK5InCVmOIKw==", - "requires": { - "@oozcitak/dom": "1.15.10", - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8", - "@types/node": "*", - "js-yaml": "3.14.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } + "xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index 864d859..2278f46 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "next": "12.0.7", "react": "17.0.2", "react-dom": "17.0.2", - "xmlbuilder2": "^3.0.2" + "xmlbuilder": "^15.1.1" }, "devDependencies": { "@types/node": "17.0.8", diff --git a/pages/api/apps/index.ts b/pages/api/apps/index.ts index dbc86eb..ac2bcbd 100644 --- a/pages/api/apps/index.ts +++ b/pages/api/apps/index.ts @@ -27,4 +27,6 @@ export default async function handler( .status(200) .json(metadata.create(acs_url, entity_id, certificate)); } + + async function downloadMetadata(req: NextApiRequest) {} } diff --git a/pages/api/apps/metadata.ts b/pages/api/apps/metadata.ts new file mode 100644 index 0000000..a2c969a --- /dev/null +++ b/pages/api/apps/metadata.ts @@ -0,0 +1,27 @@ +import { promises as fs } from 'fs'; +import type { NextApiRequest, NextApiResponse } from 'next'; +import path from 'path'; +import { metadata } from '../../../services'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + if (req.method === 'POST') { + return await download(req); + } + + async function download(req: NextApiRequest) { + const { acs_url, entity_id } = req.body; + + const certificateFilePath = path.join('data', 'x509cert.txt'); + const certificate = await fs.readFile(certificateFilePath, 'utf8'); + + const xml = await metadata.createXML(acs_url, entity_id, certificate); + + return res.send(xml); + + // res.setHeader('Content-type', 'text/xml'); + // res.setHeader('Content-Disposition', 'attachment; filename="text.xml"'); + } +} diff --git a/pages/apps/index.tsx b/pages/apps/index.tsx index 46ac3dd..b66deda 100644 --- a/pages/apps/index.tsx +++ b/pages/apps/index.tsx @@ -52,9 +52,9 @@ const Apps: NextPage = () => { ); diff --git a/services/metadata.ts b/services/metadata.ts index 6975b34..cae4478 100644 --- a/services/metadata.ts +++ b/services/metadata.ts @@ -1,3 +1,4 @@ +import * as xmlbuilder from 'xmlbuilder'; import type { IdPMetadata } from '../types'; const baseUrl = 'http://localhost:3000/saml'; @@ -18,3 +19,43 @@ export const create = ( certificate: certificate, }; }; + +const formatCert = (certificate: string) => { + return certificate + .replace('-----BEGIN CERTIFICATE-----', '') + .replace('-----END CERTIFICATE-----', '') + .trim(); +}; + +export const createXML = async ( + acs_url: string, + entity_id: string, + certificate: string +) => { + const metadata = create(acs_url, entity_id, certificate); + + const data = { + 'md:EntityDescriptor': { + '@xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata', + '@entityID': `${metadata.entity_id}`, + '@validUntil': '2026-06-22T18:39:53.000Z', + 'md:IDPSSODescriptor': { + '@WantAuthnRequestsSigned': 'false', + '@protocolSupportEnumeration': 'urn:oasis:names:tc:SAML:2.0:protocol', + 'md:KeyDescriptor': { + '@use': 'signing', + 'ds:KeyInfo': { + '@xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', + }, + 'ds:X509Data': { + 'ds:X509Certificate': { + '#text': `${formatCert(certificate)}`, + }, + }, + }, + }, + }, + }; + + return xmlbuilder.create(data).end({ pretty: true }); +};