import { request } from './../../config' ; import * as url from 'url' ; import * as cookie from 'cookie' ; import template = require ( 'lodash.template' ) ; import { Response } from 'got' ; const xmldoc = require ( 'xmldoc' ) ; import { IAuthResolver } from './../IAuthResolver' ; import { IAdfsUserCredentials } from './../IAuthOptions' ; import { IAuthResponse } from './../IAuthResponse' ; import { Cache } from './../../utils/Cache' ; import * as consts from './../../Consts' ; import { AdfsHelper } from './../../utils/AdfsHelper' ; import { SamlAssertion } from './../../utils/SamlAssertion' ; import { template as adfsSamlTokenTemplate } from './../../templates/AdfsSamlToken' ; export class AdfsCredentials implements IAuthResolver { private static CookieCache : Cache = new Cache ( ) ; private _authOptions : IAdfsUserCredentials ; constructor ( private _siteUrl , _authOptions ) { this . _authOptions = Object . assign ( { } , _authOptions ) ; this . _authOptions . username = this . _authOptions . username . replace ( /&/g , '&amp;' ) . replace ( /"/g , '&quot;' ) . replace ( /'/g , '&apos;' ) . replace ( /</g , '&lt;' ) . replace ( />/g , '&gt;' ) ; this . _authOptions . password = this . _authOptions . password . replace ( /&/g , '&amp;' ) . replace ( /"/g , '&quot;' ) . replace ( /'/g , '&apos;' ) . replace ( /</g , '&lt;' ) . replace ( />/g , '&gt;' ) ; if ( this . _authOptions . domain !== undefined ) { this . _authOptions . username = `${ this . _authOptions . domain }\\${ this . _authOptions . username }` ; } } public getAuth ( ) { const siteUrlParsed = url . parse ( this . _siteUrl ) ; const cacheKey = `${ siteUrlParsed . host }@${ this . _authOptions . username }@${ this . _authOptions . password }` ; const cachedCookie = AdfsCredentials . CookieCache . get < string > ( cacheKey ) ; if ( cachedCookie ) { return Promise . resolve ( { headers : { 'Cookie' : cachedCookie } } ) ; } return AdfsHelper . getSamlAssertion ( this . _authOptions ) . then ( ( data ) => { return this . postTokenData ( data ) ; } ) . then ( data => { const adfsCookie = this . _authOptions . adfsCookie || consts . FedAuth ; const notAfter = new Date ( data [ 0 ] ) . getTime ( ) ; const expiresIn = parseInt ( ( ( notAfter - new Date ( ) . getTime ( ) ) / 1000 ) . toString ( ) , 10 ) ; const response = data [ 1 ] ; const authCookie = adfsCookie + '=' + response . headers [ 'set-cookie' ] . map ( ( cookieString ) => cookie . parse ( cookieString ) [ adfsCookie ] ) . filter ( ( cookieString ) => typeof cookieString !== 'undefined' ) [ 0 ] ; AdfsCredentials . CookieCache . set ( cacheKey , authCookie , expiresIn ) ; return { headers : { 'Cookie' : authCookie } } ; } ) ; } private postTokenData ( samlAssertion ) { const result = template ( adfsSamlTokenTemplate ) ( { created : samlAssertion . notBefore , expires : samlAssertion . notAfter , relyingParty : this . _authOptions . relyingParty , token : samlAssertion . value } ) ; const tokenXmlDoc = new xmldoc . XmlDocument ( result ) ; const siteUrlParsed = url . parse ( this . _siteUrl ) ; const rootSiteUrl = `${ siteUrlParsed . protocol }//${ siteUrlParsed . host }` ; return Promise . all ( [ samlAssertion . notAfter , request . post ( `${ rootSiteUrl }/_trust/` , { form : { 'wa' : 'wsignin1.0' , 'wctx' : `${ rootSiteUrl }/_layouts/Authenticate.aspx?Source=%2F` , 'wresult' : tokenXmlDoc . toString ( { compressed : true } ) } } ) ] ) ; } }