From 9b86ea8b2ed390b9f68ff612c96e52c7b113f258 Mon Sep 17 00:00:00 2001 From: Kiran Date: Wed, 23 Feb 2022 19:18:20 +0530 Subject: [PATCH] Code cleanup --- pages/api/saml/auth.ts | 6 ++++-- pages/api/saml/sso.ts | 5 +++-- utils/certificate.ts | 30 +++++++++++++++++++++++++++++- utils/index.ts | 2 +- utils/request.ts | 2 +- utils/response.ts | 35 ++++------------------------------- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/pages/api/saml/auth.ts b/pages/api/saml/auth.ts index 5100b60..7eeb119 100644 --- a/pages/api/saml/auth.ts +++ b/pages/api/saml/auth.ts @@ -1,3 +1,4 @@ +import config from 'lib/env'; import type { NextApiRequest, NextApiResponse } from 'next'; import type { User } from 'types'; import { @@ -7,22 +8,23 @@ import { fetchPublicKey, signResponseXML, } from 'utils'; -import config from 'lib/env'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === 'POST') { const email = req.body.email; + if (!email.endsWith('@example.com')) { res.status(403).send(`${email} denied access`); } + const id = email.replace('@example.com', ''); + const user: User = { id, email, firstName: id, lastName: id, }; - console.log(`🏁`, user); const xml = await createResponseXML({ idpIdentityId: config.entityId, diff --git a/pages/api/saml/sso.ts b/pages/api/saml/sso.ts index b7e5403..8ddfa37 100644 --- a/pages/api/saml/sso.ts +++ b/pages/api/saml/sso.ts @@ -12,15 +12,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< async function processSAMLRequest() { const relayState = req.query.RelayState; const samlRequest = req.query.SAMLRequest; + try { const { id, audience, acsUrl, providerName } = await extractSAMLRequestAttributes(samlRequest); const params = new URLSearchParams({ id, audience, acsUrl, providerName, relayState }); + res.redirect(302, `/saml/login?${params.toString()}`); } catch (err) { console.error(err); + res.status(500).send(`Error parsing SAML request`); } - - // const audience = config.entityId; } } diff --git a/utils/certificate.ts b/utils/certificate.ts index a3623a8..3640523 100644 --- a/utils/certificate.ts +++ b/utils/certificate.ts @@ -1,4 +1,5 @@ import { promises as fs } from 'fs'; +import { asn1, pki, util } from 'node-forge'; import path from 'path'; const fetchPublicKey = async (): Promise => { @@ -9,6 +10,14 @@ const fetchPrivateKey = async (): Promise => { return await fs.readFile(path.join('data', 'key.pem'), 'ascii'); }; +function getPublicKeyPemFromCertificate(x509Certificate: string) { + const certDerBytes = util.decode64(x509Certificate); + const obj = asn1.fromDer(certDerBytes); + const cert = pki.certificateFromAsn1(obj); + + return pki.publicKeyToPem(cert.publicKey); +} + const stripCertHeaderAndFooter = (cert: string): string => { cert = cert.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, ''); cert = cert.replace(/-+END CERTIFICATE-+\r?\n?/, ''); @@ -17,4 +26,23 @@ const stripCertHeaderAndFooter = (cert: string): string => { return cert; }; -export { fetchPublicKey, fetchPrivateKey, stripCertHeaderAndFooter }; +function GetKeyInfo(x509Certificate: string, signatureConfig: any = {}) { + x509Certificate = stripCertHeaderAndFooter(x509Certificate); + + this.getKeyInfo = () => { + const prefix = signatureConfig.prefix ? `${signatureConfig.prefix}:` : ''; + return `<${prefix}X509Data><${prefix}X509Certificate>${x509Certificate}`; + }; + + this.getKey = () => { + return getPublicKeyPemFromCertificate(x509Certificate).toString(); + }; +} + +export { + fetchPublicKey, + fetchPrivateKey, + stripCertHeaderAndFooter, + getPublicKeyPemFromCertificate, + GetKeyInfo, +}; diff --git a/utils/index.ts b/utils/index.ts index 943cb83..fa460b1 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -1,4 +1,4 @@ export * from './certificate'; +export * from './idp'; export * from './request'; export * from './response'; -export * from './idp'; diff --git a/utils/request.ts b/utils/request.ts index b7cd78c..1f3ed25 100644 --- a/utils/request.ts +++ b/utils/request.ts @@ -1,5 +1,5 @@ -import xml2js from 'xml2js'; import { promisify } from 'util'; +import xml2js from 'xml2js'; import { inflateRaw } from 'zlib'; const inflateRawAsync = promisify(inflateRaw); diff --git a/utils/response.ts b/utils/response.ts index 2bfd9af..cdb09be 100644 --- a/utils/response.ts +++ b/utils/response.ts @@ -1,8 +1,8 @@ -import { User } from '../types'; -import xmlbuilder from 'xmlbuilder'; import crypto from 'crypto'; -import { SignedXml, FileKeyInfo } from 'xml-crypto'; -import { pki, util, asn1 } from 'node-forge'; +import { SignedXml } from 'xml-crypto'; +import xmlbuilder from 'xmlbuilder'; +import { User } from '../types'; +import { GetKeyInfo } from './certificate'; const createResponseXML = async (params: { idpIdentityId: string; @@ -156,33 +156,6 @@ const createResponseForm = (relayState: string, encodedSamlResponse: string, acs return formElements.join(''); }; -function getPublicKeyPemFromCertificate(x509Certificate: string) { - const certDerBytes = util.decode64(x509Certificate); - const obj = asn1.fromDer(certDerBytes); - const cert = pki.certificateFromAsn1(obj); - return pki.publicKeyToPem(cert.publicKey); -} - -const stripCertHeaderAndFooter = (cert: string): string => { - cert = cert.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, ''); - cert = cert.replace(/-+END CERTIFICATE-+\r?\n?/, ''); - cert = cert.replace(/\r\n/g, '\n'); - return cert; -}; - -function GetKeyInfo(x509Certificate: string, signatureConfig: any = {}) { - x509Certificate = stripCertHeaderAndFooter(x509Certificate); - - this.getKeyInfo = () => { - const prefix = signatureConfig.prefix ? `${signatureConfig.prefix}:` : ''; - return `<${prefix}X509Data><${prefix}X509Certificate>${x509Certificate}`; - }; - - this.getKey = () => { - return getPublicKeyPemFromCertificate(x509Certificate).toString(); - }; -} - const signResponseXML = async (xml: string, signingKey: any, publicKey: any): Promise => { const sig = new SignedXml(); const responseXPath =