import Metadata, { MetadataInterface } from './metadata';import { MetadataSpConstructor, MetadataSpOptions } from './types';import { namespace, elementsOrder as order } from './urn';import libsaml from './libsaml';import { isNonEmptyArray, isString } from './utility';import xml from 'xml';
export interface SpMetadataInterface extends MetadataInterface {
}
interface MetaElement { KeyDescriptor?: any[]; NameIDFormat?: any[]; SingleLogoutService?: any[]; AssertionConsumerService?: any[]; AttributeConsumingService?: any[];}
export default function(meta: MetadataSpConstructor) { return new SpMetadata(meta);}
export class SpMetadata extends Metadata {
constructor(meta: MetadataSpConstructor) {
const isFile = isString(meta) || meta instanceof Buffer;
if (!isFile) {
const { elementsOrder = order.default, entityID, signingCert, encryptCert, authnRequestsSigned = false, wantAssertionsSigned = false, wantMessageSigned = false, signatureConfig, nameIDFormat = [], singleLogoutService = [], assertionConsumerService = [], } = meta as MetadataSpOptions;
const descriptors: MetaElement = { KeyDescriptor: [], NameIDFormat: [], SingleLogoutService: [], AssertionConsumerService: [], AttributeConsumingService: [], };
const SPSSODescriptor: any[] = [{ _attr: { AuthnRequestsSigned: String(authnRequestsSigned), WantAssertionsSigned: String(wantAssertionsSigned), protocolSupportEnumeration: namespace.names.protocol, }, }];
if (wantMessageSigned && signatureConfig === undefined) { console.warn('Construct service provider - missing signatureConfig'); }
if (signingCert) { descriptors.KeyDescriptor!.push(libsaml.createKeySection('signing', signingCert).KeyDescriptor); } else { }
if (encryptCert) { descriptors.KeyDescriptor!.push(libsaml.createKeySection('encryption', encryptCert).KeyDescriptor); } else { }
if (isNonEmptyArray(nameIDFormat)) { nameIDFormat.forEach(f => descriptors.NameIDFormat!.push(f)); } else { descriptors.NameIDFormat!.push(namespace.format.emailAddress); }
if (isNonEmptyArray(singleLogoutService)) { singleLogoutService.forEach(a => { const attr: any = { Binding: a.Binding, Location: a.Location, }; if (a.isDefault) { attr.isDefault = true; } descriptors.SingleLogoutService!.push([{ _attr: attr }]); }); }
if (isNonEmptyArray(assertionConsumerService)) { let indexCount = 0; assertionConsumerService.forEach(a => { const attr: any = { index: String(indexCount++), Binding: a.Binding, Location: a.Location, }; if (a.isDefault) { attr.isDefault = true; } descriptors.AssertionConsumerService!.push([{ _attr: attr }]); }); } else { }
const existedElements = elementsOrder.filter(name => isNonEmptyArray(descriptors[name])); existedElements.forEach(name => { descriptors[name].forEach(e => SPSSODescriptor.push({ [name]: e })); });
meta = xml([{ EntityDescriptor: [{ _attr: { entityID, 'xmlns': namespace.names.metadata, 'xmlns:assertion': namespace.names.assertion, 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', }, }, { SPSSODescriptor }], }]);
}
super(meta as string | Buffer, [ { key: 'spSSODescriptor', localPath: ['EntityDescriptor', 'SPSSODescriptor'], attributes: ['WantAssertionsSigned', 'AuthnRequestsSigned'], }, { key: 'assertionConsumerService', localPath: ['EntityDescriptor', 'SPSSODescriptor', 'AssertionConsumerService'], attributes: ['Binding', 'Location', 'isDefault', 'index'], } ]);
}
public isWantAssertionsSigned(): boolean { return this.meta.spSSODescriptor.wantAssertionsSigned === 'true'; } public isAuthnRequestSigned(): boolean { return this.meta.spSSODescriptor.authnRequestsSigned === 'true'; } public getAssertionConsumerService(binding: string): string | string[] { if (isString(binding)) { let location; const bindName = namespace.binding[binding]; if (isNonEmptyArray(this.meta.assertionConsumerService)) { this.meta.assertionConsumerService.forEach(obj => { if (obj.binding === bindName) { location = obj.location; return; } }); } else { if (this.meta.assertionConsumerService.binding === bindName) { location = this.meta.assertionConsumerService.location; } } return location; } return this.meta.assertionConsumerService; }}