2022-02-22 06:14:12 +00:00
|
|
|
import { promisify } from 'util';
|
2022-02-23 13:48:20 +00:00
|
|
|
import xml2js from 'xml2js';
|
2022-02-22 06:14:12 +00:00
|
|
|
import { inflateRaw } from 'zlib';
|
2022-02-21 14:31:47 +00:00
|
|
|
|
2022-02-22 05:35:42 +00:00
|
|
|
const inflateRawAsync = promisify(inflateRaw);
|
2022-02-21 14:31:47 +00:00
|
|
|
|
|
|
|
|
// Parse XML
|
|
|
|
|
const parseXML = (xml: string): Promise<Record<string, any>> => {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2023-03-24 05:12:47 +00:00
|
|
|
xml2js.parseString(
|
|
|
|
|
xml,
|
|
|
|
|
{
|
|
|
|
|
tagNameProcessors: [xml2js.processors.stripPrefix],
|
|
|
|
|
strict: true,
|
|
|
|
|
},
|
|
|
|
|
(err: Error | null, result: any) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
reject(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resolve(result);
|
2022-02-21 14:31:47 +00:00
|
|
|
}
|
2023-03-24 05:12:47 +00:00
|
|
|
);
|
2022-02-21 14:31:47 +00:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-02 21:06:04 +00:00
|
|
|
// Decode the base64 string
|
|
|
|
|
const decodeBase64 = async (string: string, isDeflated: boolean) => {
|
|
|
|
|
return isDeflated
|
|
|
|
|
? (await inflateRawAsync(Buffer.from(string, 'base64'))).toString()
|
|
|
|
|
: Buffer.from(string, 'base64').toString();
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-21 14:31:47 +00:00
|
|
|
// Parse SAMLRequest attributes
|
2023-03-24 23:01:42 +00:00
|
|
|
const extractSAMLRequestAttributes = async (rawRequest: string, isPost = true) => {
|
2022-03-02 21:06:04 +00:00
|
|
|
const result = await parseXML(rawRequest);
|
2022-02-21 14:31:47 +00:00
|
|
|
|
2023-03-24 05:12:47 +00:00
|
|
|
const attributes = result['AuthnRequest']['$'];
|
|
|
|
|
const issuer = result['AuthnRequest']['Issuer'];
|
2022-03-02 21:06:04 +00:00
|
|
|
|
2023-03-24 05:12:47 +00:00
|
|
|
const publicKey = result['AuthnRequest']['Signature']
|
|
|
|
|
? result['AuthnRequest']['Signature'][0]['KeyInfo'][0]['X509Data'][0]['X509Certificate'][0]
|
2022-10-12 18:11:50 +00:00
|
|
|
: null;
|
|
|
|
|
|
2023-03-24 23:01:42 +00:00
|
|
|
if (!publicKey && isPost) {
|
2022-10-12 18:11:50 +00:00
|
|
|
throw new Error('Missing signature');
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 14:31:47 +00:00
|
|
|
return {
|
2022-02-22 05:35:42 +00:00
|
|
|
id: attributes.ID,
|
|
|
|
|
acsUrl: attributes.AssertionConsumerServiceURL,
|
|
|
|
|
providerName: attributes.ProviderName,
|
2022-02-22 06:14:12 +00:00
|
|
|
audience: issuer[0]['_'],
|
2022-10-12 18:11:50 +00:00
|
|
|
publicKey,
|
2022-02-21 14:31:47 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2022-04-26 17:02:12 +00:00
|
|
|
export { extractSAMLRequestAttributes, decodeBase64 };
|