file author tngan
*  desc import { isString , isNonEmptyArray } from './utility' ; import { namespace , wording , algorithms , messageConfigurations } from './urn' ; import * as uuid from 'uuid' ; import IdpMetadata , { IdpMetadata as IdpMetadataConstructor } from './metadata-idp' ; import SpMetadata , { SpMetadata as SpMetadataConstructor } from './metadata-sp' ; import redirectBinding from './binding-redirect' ; import postBinding from './binding-post' ; import { MetadataIdpConstructor , MetadataSpConstructor , EntitySetting } from './types' ; import { flow , FlowResult } from './flow' ; const dataEncryptionAlgorithm = algorithms . encryption . data ; const keyEncryptionAlgorithm = algorithms . encryption . key ; const signatureAlgorithms = algorithms . signature ; const messageSigningOrders = messageConfigurations . signingOrder ; const defaultEntitySetting = { wantLogoutResponseSigned : false , messageSigningOrder : messageSigningOrders . SIGN_THEN_ENCRYPT , wantLogoutRequestSigned : false , allowCreate : false , isAssertionEncrypted : false , requestSignatureAlgorithm : signatureAlgorithms . RSA_SHA256 , dataEncryptionAlgorithm : dataEncryptionAlgorithm . AES_256 , keyEncryptionAlgorithm : keyEncryptionAlgorithm . RSA_1_5 , generateID : ( ) : string => ( '_' + uuid . v4 ( ) ) , relayState : '' , } ; export interface ESamlHttpRequest { query ? : any ; body ? : any ; octetString ? : string ; } export interface BindingContext { context : string ; id : string ; } export interface PostBindingContext extends BindingContext { relayState ? : string ; entityEndpoint : string ; type : string ; } export interface SimpleSignBindingContext extends PostBindingContext { sigAlg ? : string ; signature ? : string ; keyInfo ? : string ; } export interface SimpleSignComputedContext extends BindingContext { sigAlg ? : string ; signature ? : string ; } export interface ParseResult { samlContent : string ; extract : any ; sigAlg : string ; } export type EntityConstructor = ( MetadataIdpConstructor | MetadataSpConstructor ) & { metadata ? : string | Buffer ; } ; export default class Entity { entitySetting : EntitySetting ; entityType : string ; entityMeta : IdpMetadataConstructor | SpMetadataConstructor ; param entitySetting param entityMeta constructor ( entitySetting , entityType ) { this . entitySetting = Object . assign ( { } , defaultEntitySetting , entitySetting ) ; const metadata = entitySetting . metadata || entitySetting ; switch ( entityType ) { case 'idp' : this . entityMeta = IdpMetadata ( metadata ) ; this . entitySetting . wantAuthnRequestsSigned = this . entityMeta . isWantAuthnRequestsSigned ( ) ; this . entitySetting . nameIDFormat = this . entityMeta . getNameIDFormat ( ) || this . entitySetting . nameIDFormat ; break ; case 'sp' : this . entityMeta = SpMetadata ( metadata ) ; this . entitySetting . authnRequestsSigned = this . entityMeta . isAuthnRequestSigned ( ) ; this . entitySetting . wantAssertionsSigned = this . entityMeta . isWantAssertionsSigned ( ) ; this . entitySetting . nameIDFormat = this . entityMeta . getNameIDFormat ( ) || this . entitySetting . nameIDFormat ; break ; default : throw new Error ( 'ERR_UNDEFINED_ENTITY_TYPE' ) ; } } desc return { object } getEntitySetting ( ) { return this . entitySetting ; } desc return { string } getMetadata ( ) { return this . entityMeta . getMetadata ( ) ; } desc param { string } exportFile exportMetadata ( exportFile ) { return this . entityMeta . exportMetadata ( exportFile ) ; } param { string param { string } metaField return { boolean } verifyFields ( field , metaField ) { if ( isString ( field ) ) { return field === metaField ; } if ( isNonEmptyArray ( field ) ) { let res = true ; ( field as string [ ] ) . forEach ( f => { if ( f !== metaField ) { res = false ; return ; } } ) ; return res ; } return false ; } desc param { ServiceProvider } sp param { string } binding param { object } user param { string } relayState param { function } customTagReplacement createLogoutRequest ( targetEntity , binding , user , relayState = '' , customTagReplacement ? ) { if ( binding === wording . binding . redirect ) { return redirectBinding . logoutRequestRedirectURL ( user , { init : this , target : targetEntity , } , relayState , customTagReplacement ) ; } if ( binding === wording . binding . post ) { const entityEndpoint = targetEntity . entityMeta . getSingleLogoutService ( binding ) ; const context = postBinding . base64LogoutRequest ( user , "/*[local-name(.)='LogoutRequest']" , { init : this , target : targetEntity } , customTagReplacement ) ; return { ... context , relayState , entityEndpoint , type : 'SAMLRequest' , } ; } throw new Error ( 'ERR_UNDEFINED_BINDING' ) ; } desc param { IdentityProvider } idp param { object } requestInfo param { string } relayState param { string } binding param { function } customTagReplacement createLogoutResponse ( target , requestInfo , binding , relayState = '' , customTagReplacement ? ) { const protocol = namespace . binding [ binding ] ; if ( protocol === namespace . binding . redirect ) { return redirectBinding . logoutResponseRedirectURL ( requestInfo , { init : this , target , } , relayState , customTagReplacement ) ; } if ( protocol === namespace . binding . post ) { const context = postBinding . base64LogoutResponse ( requestInfo , { init : this , target , } , customTagReplacement ) ; return { ... context , relayState , entityEndpoint : target . entityMeta . getSingleLogoutService ( binding ) , type : 'SAMLResponse' , } ; } throw new Error ( 'ERR_CREATE_LOGOUT_RESPONSE_UNDEFINED_BINDING' ) ; } desc param { IdentityProvider } idp param { string } binding param { request } req return { Promise } parseLogoutRequest ( from , binding , request ) { const self = this ; return flow ( { from : from , self : self , type : 'logout' , parserType : 'LogoutRequest' , checkSignature : this . entitySetting . wantLogoutRequestSigned , binding : binding , request : request , } ) ; } desc param { object } config param { string } binding param { request } req return { Promise } parseLogoutResponse ( from , binding , request ) { const self = this ; return flow ( { from : from , self : self , type : 'logout' , parserType : 'LogoutResponse' , checkSignature : self . entitySetting . wantLogoutResponseSigned , binding : binding , request : request } ) ; } }