UNPKG

libsaml

Version:

Parse SAML2 attributes into a JavaScript object.

91 lines (77 loc) 2.69 kB
// LibSaml // ======= // A library for parsing SAML attributes // into a POJO (Plain Old JavaScript Object) // Require dependencies const xmldom = require('xmldom'); const xpath = require('xpath'); // LibSaml // ------- // Constructor function. Saves a copy // of the raw SAML you pass to it and // a copy that's parsed into a JS object. // // `response` [String] - A SAML response string function LibSaml(response) { this.rawSaml = response; this.parsedSaml = this.parse(response); } // LibSaml.parse // ------------- // Private function. // Parses raw SAML assertion to an array of objects. LibSaml.prototype.parse = function parse(saml) { const saml2Namespace = 'urn:oasis:names:tc:SAML:2.0:assertion'; const xpAttribute = '//saml2:Attribute'; const xpName = 'string(@Name)'; const xpVal = 'saml2:AttributeValue'; const xml = Buffer.from(saml, 'base64').toString('ascii'); const doc = new xmldom.DOMParser().parseFromString(xml); const select = xpath.useNamespaces({ saml2: saml2Namespace }); const attributes = select(xpAttribute, doc).reduce( (acc, attr) => acc.concat( { name: select(xpName, attr), value: select(xpVal, attr).reduce((a, b) => [].concat(a, b.textContent), []), }, ), [], ); return { attributes }; }; // LibSaml.toJSON // -------------- // Returns parsed SAML as a JSON string. // (Basically just an alias to `JSON.stringify()`). LibSaml.prototype.toJSON = function toJSON() { return JSON.stringify(this.parsedSaml); }; // LibSaml.getAttribute // ----------- // Get the value of a SAML attribute by using its // original SAML attribute Name from the raw XML. // // `key` [String] - The attribute name as it appears in the raw SAML // // Example: // // Given the following SAML/XML // // <saml2:Attribute Name="First Name"> // // <saml2:AttributeValue>John</saml2:AttributeValue> // // </saml2:Attribute> // console.log(parser.get('first name')[0]); //=> John LibSaml.prototype.getAttribute = function get(key) { const attributes = this.parsedSaml.attributes; const predicate = element => element.name.toLowerCase() === key.toLowerCase(); return [].concat(...attributes.filter(predicate).map(x => x.value)); }; // LibSaml.toObject // ---------------- // Returns the parsed SAML as a JS object. // This does not do any further processing, it // just returns the object's internal value // of `this.parsedSaml`. LibSaml.prototype.toObject = function toObject() { return this.parsedSaml; }; module.exports = LibSaml;