All files / src/auth/resolvers OnpremiseFbaCredentials.ts

88.37% Statements 38/43
58.33% Branches 7/12
100% Functions 5/5
88.1% Lines 37/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 1111x 1x 1x 1x 1x 1x 1x 1x   1x         1x 1x   1x   1x   3x       3x 3x 3x 3x   3x 2x             1x                 1x   1x                       1x         1x   1x             1x   1x 1x           1x     1x       1x 1x 1x       1x   1x   1x                  
import * as Promise from 'bluebird';
import * as _ from 'lodash';
import * as util from 'util';
import * as fs from 'fs';
import * as path from 'path';
import * as url from 'url';
import * as request from 'request-promise';
import * as cookie from 'cookie';
 
let xmldoc: any = require('xmldoc');
 
import { IAuthResolver } from './../IAuthResolver';
import { IOnpremiseUserCredentials } from './../IAuthOptions';
import { IAuthResponse } from './../IAuthResponse';
import { Cache } from './../../utils/Cache';
import * as consts from './../../Consts';
 
export class OnpremiseFbaCredentials implements IAuthResolver {
 
  private static CookieCache: Cache = new Cache();
 
  constructor(private _siteUrl: string, private _authOptions: IOnpremiseUserCredentials) { }
 
  public getAuth(): Promise<IAuthResponse> {
 
    let parsedUrl: url.Url = url.parse(this._siteUrl);
    let host: string = parsedUrl.host;
    let cacheKey: string = util.format('%s@%s', host, this._authOptions.username);
    let cachedCookie: string = OnpremiseFbaCredentials.CookieCache.get<string>(cacheKey);
 
    if (cachedCookie) {
      return Promise.resolve({
        headers: {
          'Cookie': cachedCookie
        }
      });
    }
 
    let soapBody: string = _.template(
      fs.readFileSync(
        path.join(__dirname, '..', '..', '..', 'templates', 'fba_login_wsfed.tmpl')
      ).toString()
    )({
      username: this._authOptions.username,
      password: this._authOptions.password
    });
 
    let fbaEndPoint = `${parsedUrl.protocol}//${host}/${consts.FbaAuthEndpoint}`;
 
    return request({
      url: fbaEndPoint,
      method: 'POST',
      headers: {
        'Content-Type': 'text/xml; charset=utf-8',
        'Content-Length': soapBody.length
      },
      body: soapBody,
      json: false,
      simple: false,
      strictSSL: false,
      transform: (body: any, response: any, resolveWithFullResponse: any) => {
        return response;
      }
    } as any)
      .then((response: any) => {
 
        let xmlDoc: any = new xmldoc.XmlDocument(response.body);
 
        Iif (xmlDoc.name === 'm:error') {
          let errorCode: string = xmlDoc.childNamed('m:code').val;
          let errorMessage: string = xmlDoc.childNamed('m:message').val;
          throw new Error(`${errorCode}, ${errorMessage}`);
        }
 
        let errorCode: string =
          xmlDoc.childNamed('soap:Body').childNamed('LoginResponse').childNamed('LoginResult').childNamed('ErrorCode').val;
        let cookieName: string =
          xmlDoc.childNamed('soap:Body').childNamed('LoginResponse').childNamed('LoginResult').childNamed('CookieName').val;
        let diffSeconds: number = parseInt(
          xmlDoc.childNamed('soap:Body').childNamed('LoginResponse').childNamed('LoginResult').childNamed('TimeoutSeconds').val,
          null
        );
        let cookieValue: string;
 
        Iif (errorCode === 'PasswordNotMatch') {
          throw new Error(`Password doesn't not match`);
        }
        Iif (errorCode !== 'NoError') {
          throw new Error(errorCode);
        }
 
        (response.headers['set-cookie'] || []).forEach((headerCookie: string) => {
          Eif (headerCookie.indexOf(cookieName) !== -1) {
            cookieValue = cookie.parse(headerCookie)[cookieName];
          }
        });
 
        let authCookie = `${cookieName}=${cookieValue}`;
 
        OnpremiseFbaCredentials.CookieCache.set(cacheKey, authCookie, diffSeconds);
 
        return {
          headers: {
            'Cookie': authCookie
          }
        };
 
      }) as Promise<IAuthResponse>;
  };
}