diff --git a/src/passport-saml/saml.ts b/src/passport-saml/saml.ts index e2a3e206..e2b91ec2 100644 --- a/src/passport-saml/saml.ts +++ b/src/passport-saml/saml.ts @@ -62,9 +62,9 @@ async function processValidlySignedPostRequestAsync( } else { throw new Error("Missing SAML issuer"); } - const nameID = await util.promisify(self.getNameID).bind(self)(self, dom); + const nameID = await self.getNameIDAsync(self, dom); if (nameID) { - profile.nameID = nameID.value; + profile.nameID = nameID.value!; if (nameID.format) { profile.nameIDFormat = nameID.format; } @@ -250,21 +250,6 @@ class SAML { samlMessage.Signature = signer.sign(this.keyToPEM(this.options.privateKey), "base64"); } - /** - * - * @deprecated - */ - generateAuthorizeRequest( - req: Request, - isPassive: boolean, - isHttpPostBinding: boolean, - callback: (err: Error | null, request?: string) => void - ) { - return util.callbackify(() => - this.generateAuthorizeRequestAsync(req, isPassive, isHttpPostBinding) - )(callback); - } - async generateAuthorizeRequestAsync( req: Request, isPassive: boolean, @@ -466,20 +451,6 @@ class SAML { return xmlbuilder.create(request).end(); } - /** - * @deprecated - */ - requestToUrl( - request: string | null | undefined, - response: string | null, - operation: string, - additionalParameters: querystring.ParsedUrlQuery, - callback: (err: Error | null, url?: string | null | undefined) => void - ) { - util.callbackify(() => - this.requestToUrlAsync(request, response, operation, additionalParameters) - )(callback); - } async requestToUrlAsync( request: string | null | undefined, response: string | null, @@ -570,17 +541,6 @@ class SAML { return additionalParams; } - /** - * @deprecated - */ - getAuthorizeUrl( - req: Request, - options: AuthorizeOptions, - callback: (err: Error | null, url: string) => void - ): void { - util.callbackify(() => this.getAuthorizeUrlAsync(req, options))(callback); - } - async getAuthorizeUrlAsync(req: Request, options: AuthorizeOptions): Promise { const request = await this.generateAuthorizeRequestAsync(req, this.options.passive, false); const operation = "authorize"; @@ -593,12 +553,6 @@ class SAML { ); } - /** - * @deprecated - */ - getAuthorizeForm(req: Request, callback: (err: Error | null, data?: unknown) => void) { - util.callbackify(() => this.getAuthorizeFormAsync(req))(callback); - } async getAuthorizeFormAsync(req: Request) { // The quoteattr() function is used in a context, where the result will not be evaluated by javascript // but must be interpreted by an XML or HTML parser, and it must absolutely avoid breaking the syntax @@ -675,16 +629,6 @@ class SAML { ].join("\r\n"); } - /** - * @deprecated - */ - getLogoutUrl( - req: RequestWithUser, - options: AuthenticateOptions & AuthorizeOptions, - callback: (err: Error | null, url?: string | null) => void - ) { - util.callbackify(() => this.getLogoutUrlAsync(req, options))(callback); - } async getLogoutUrlAsync(req: RequestWithUser, options: AuthenticateOptions & AuthorizeOptions) { const request = await this.generateLogoutRequest(req); const operation = "logout"; @@ -813,18 +757,6 @@ class SAML { return sig.checkSignature(fullXml); } - /** - * @deprecated - */ - validatePostResponse( - container: Record, - callback: (err: Error | null, profile?: Profile | null, loggedOut?: boolean) => void - ) { - this.validatePostResponseAsync(container) - .then((res) => callback(null, res.profile, res.loggedOut)) - .catch((err) => callback(err)); - } - async validatePostResponseAsync( container: Record ): Promise<{ profile?: Profile | null; loggedOut?: boolean }> { @@ -1007,19 +939,6 @@ class SAML { } } - /** - * @deprecated - */ - validateRedirect( - container: ParsedQs, - originalQuery: string | null, - callback: (err: Error | null, profile?: Profile | null, loggedOut?: boolean) => void - ) { - this.validateRedirectAsync(container, originalQuery) - .then((res) => callback(null, res.profile, res.loggedOut)) - .catch((err) => callback(err)); - } - async validateRedirectAsync( container: ParsedQs, originalQuery: string | null @@ -1151,24 +1070,6 @@ class SAML { } } - /** - * @deprecated - */ - processValidlySignedAssertion( - xml: xml2js.convertableToString, - samlResponseXml: string, - inResponseTo: string, - callback: ( - err: Error | null, - profile?: Profile | undefined, - loggedOut?: boolean | undefined - ) => void - ) { - this.processValidlySignedAssertionAsync(xml, samlResponseXml, inResponseTo) - .then((res) => callback(null, res.profile, res.loggedOut)) - .catch((err) => callback(err)); - } - async processValidlySignedAssertionAsync( xml: xml2js.convertableToString, samlResponseXml: string, @@ -1391,18 +1292,6 @@ class SAML { return null; } - /** - * @deprecated - */ - validatePostRequest( - container: Record, - callback: (err: Error | null, profile?: Profile, loggedOut?: boolean) => void - ) { - this.validatePostRequestAsync(container) - .then((res) => callback(null, res.profile, res.loggedOut)) - .catch((err) => callback(err)); - } - async validatePostRequestAsync( container: Record ): Promise<{ profile?: Profile; loggedOut?: boolean }> { @@ -1422,13 +1311,6 @@ class SAML { return await processValidlySignedPostRequestAsync(this, doc, dom); } - /** - * @deprecated - */ - getNameID(self: SAML, doc: Node, callback: (err: Error | null, nameID?: XMLOutput) => void) { - return util.callbackify(() => this.getNameIDAsync(self, doc)).bind(this)(callback); - } - async getNameIDAsync(self: SAML, doc: Node): Promise { const nameIds = xmlCrypto.xpath( doc, diff --git a/src/passport-saml/strategy.ts b/src/passport-saml/strategy.ts index 365a3ed0..8f4fc487 100644 --- a/src/passport-saml/strategy.ts +++ b/src/passport-saml/strategy.ts @@ -45,12 +45,13 @@ class Strategy extends PassportStrategy { authenticate(req: RequestWithUser, options: AuthenticateOptions): void { options.samlFallback = options.samlFallback || "login-request"; - - const validateCallback = (err: Error | null, profile?: Profile | null, loggedOut?: boolean) => { - if (err) { - return this.error(err); - } - + const validateCallback = ({ + profile, + loggedOut, + }: { + profile?: Profile | null; + loggedOut?: boolean; + }) => { if (loggedOut) { req.logout(); if (profile) { @@ -93,30 +94,42 @@ class Strategy extends PassportStrategy { if (req.query && (req.query.SAMLResponse || req.query.SAMLRequest)) { const originalQuery = url.parse(req.url).query; - this._saml.validateRedirect(req.query, originalQuery, validateCallback); + this._saml + .validateRedirectAsync(req.query, originalQuery) + .then(validateCallback) + .catch((err) => this.error(err)); } else if (req.body && req.body.SAMLResponse) { - this._saml.validatePostResponse(req.body, validateCallback); + this._saml + .validatePostResponseAsync(req.body) + .then(validateCallback) + .catch((err) => this.error(err)); } else if (req.body && req.body.SAMLRequest) { - this._saml.validatePostRequest(req.body, validateCallback); + this._saml + .validatePostRequestAsync(req.body) + .then(validateCallback) + .catch((err) => this.error(err)); } else { const requestHandler = { - "login-request": () => { - if (this._saml.options.authnRequestBinding === "HTTP-POST") { - this._saml.getAuthorizeForm(req, (err: Error | null, data?: any) => { - if (err) { - this.error(err); - } else { - const res = req.res!; - res.send(data); - } - }); - } else { - // Defaults to HTTP-Redirect - this._saml.getAuthorizeUrl(req, options, redirectIfSuccess); + "login-request": async () => { + try { + if (this._saml.options.authnRequestBinding === "HTTP-POST") { + const data = await this._saml.getAuthorizeFormAsync(req); + const res = req.res!; + res.send(data); + } else { + // Defaults to HTTP-Redirect + this.redirect(await this._saml.getAuthorizeUrlAsync(req, options)); + } + } catch (err) { + this.error(err); } }, - "logout-request": () => { - this._saml.getLogoutUrl(req, options, redirectIfSuccess); + "logout-request": async () => { + try { + this.redirect(await this._saml.getLogoutUrlAsync(req, options)); + } catch (err) { + this.error(err); + } }, }[options.samlFallback]; @@ -129,7 +142,10 @@ class Strategy extends PassportStrategy { } logout(req: RequestWithUser, callback: (err: Error | null, url?: string | null) => void): void { - this._saml.getLogoutUrl(req, {}, callback); + this._saml + .getLogoutUrlAsync(req, {}) + .then((url) => callback(null, url)) + .catch((err) => callback(err)); } generateServiceProviderMetadata( diff --git a/test/multiSamlStrategy.spec.ts b/test/multiSamlStrategy.spec.ts index d8939609..e1c189af 100644 --- a/test/multiSamlStrategy.spec.ts +++ b/test/multiSamlStrategy.spec.ts @@ -115,8 +115,8 @@ describe("MultiSamlStrategy#authenticate", function () { describe("MultiSamlStrategy#authorize", function () { beforeEach(function () { - this.getAuthorizeFormStub = sinon.stub(SAML.prototype, "getAuthorizeForm"); - this.getAuthorizeUrlStub = sinon.stub(SAML.prototype, "getAuthorizeUrl"); + this.getAuthorizeFormStub = sinon.stub(SAML.prototype, "getAuthorizeFormAsync").resolves(); + this.getAuthorizeUrlStub = sinon.stub(SAML.prototype, "getAuthorizeUrlAsync").resolves(); }); afterEach(function () { diff --git a/test/samlTests.spec.ts b/test/samlTests.spec.ts index 2f6c1998..c0892509 100644 --- a/test/samlTests.spec.ts +++ b/test/samlTests.spec.ts @@ -42,136 +42,64 @@ describe("SAML.js", function () { }); describe("getAuthorizeUrl", function () { - it("calls callback with right host", function (done) { - saml.getAuthorizeUrl(req, {}, function (err, target) { - try { - url.parse(target!).host!.should.equal("exampleidp.com"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with right host", async () => { + const target = await saml.getAuthorizeUrlAsync(req, {}); + url.parse(target!).host!.should.equal("exampleidp.com"); }); - it("calls callback with right protocol", function (done) { - saml.getAuthorizeUrl(req, {}, function (err, target) { - try { - url.parse(target!).protocol!.should.equal("https:"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with right protocol", async () => { + const target = await saml.getAuthorizeUrlAsync(req, {}); + url.parse(target!).protocol!.should.equal("https:"); }); - it("calls callback with right path", function (done) { - saml.getAuthorizeUrl(req, {}, function (err, target) { - try { - url.parse(target!).pathname!.should.equal("/path"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with right path", async () => { + const target = await saml.getAuthorizeUrlAsync(req, {}); + url.parse(target!).pathname!.should.equal("/path"); }); - it("calls callback with original query string", function (done) { - saml.getAuthorizeUrl(req, {}, function (err, target) { - try { - url.parse(target!, true).query["key"]!.should.equal("value"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with original query string", async () => { + const target = await saml.getAuthorizeUrlAsync(req, {}); + url.parse(target!, true).query["key"]!.should.equal("value"); }); - it("calls callback with additional run-time params in query string", function (done) { - saml.getAuthorizeUrl(req, options, function (err, target) { - try { - Object.keys(url.parse(target!, true).query).should.have.length(3); - url.parse(target!, true).query["key"]!.should.equal("value"); - url.parse(target!, true).query["SAMLRequest"]!.should.not.be.empty(); - url.parse(target!, true).query["additionalKey"]!.should.equal("additionalValue"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with additional run-time params in query string", async () => { + const target = await saml.getAuthorizeUrlAsync(req, options); + Object.keys(url.parse(target!, true).query).should.have.length(3); + url.parse(target!, true).query["key"]!.should.equal("value"); + url.parse(target!, true).query["SAMLRequest"]!.should.not.be.empty(); + url.parse(target!, true).query["additionalKey"]!.should.equal("additionalValue"); }); // NOTE: This test only tests existence of the assertion, not the correctness - it("calls callback with saml request object", function (done) { - saml.getAuthorizeUrl(req, {}, function (err, target) { - try { - should(url.parse(target!, true).query).have.property("SAMLRequest"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with saml request object", async () => { + const target = await saml.getAuthorizeUrlAsync(req, {}); + should(url.parse(target!, true).query).have.property("SAMLRequest"); }); }); describe("getLogoutUrl", function () { - it("calls callback with right host", function (done) { - saml.getLogoutUrl(req, {}, function (err, target) { - try { - url.parse(target!).host!.should.equal("exampleidp.com"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with right host", async () => { + const target = await saml.getLogoutUrlAsync(req, {}); + url.parse(target!).host!.should.equal("exampleidp.com"); }); - it("calls callback with right protocol", function (done) { - saml.getLogoutUrl(req, {}, function (err, target) { - try { - url.parse(target!).protocol!.should.equal("https:"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with right protocol", async () => { + const target = await saml.getLogoutUrlAsync(req, {}); + url.parse(target!).protocol!.should.equal("https:"); }); - it("calls callback with right path", function (done) { - saml.getLogoutUrl(req, {}, function (err, target) { - try { - url.parse(target!).pathname!.should.equal("/path"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with right path", async () => { + const target = await saml.getLogoutUrlAsync(req, {}); + url.parse(target!).pathname!.should.equal("/path"); }); - it("calls callback with original query string", function (done) { - saml.getLogoutUrl(req, {}, function (err, target) { - try { - url.parse(target!, true).query["key"]!.should.equal("value"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with original query string", async () => { + const target = await saml.getLogoutUrlAsync(req, {}); + url.parse(target!, true).query["key"]!.should.equal("value"); }); - it("calls callback with additional run-time params in query string", function (done) { - saml.getLogoutUrl(req, options, function (err, target) { - try { - Object.keys(url.parse(target!, true).query).should.have.length(3); - url.parse(target!, true).query["key"]!.should.equal("value"); - url.parse(target!, true).query["SAMLRequest"]!.should.not.be.empty(); - url.parse(target!, true).query["additionalKey"]!.should.equal("additionalValue"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with additional run-time params in query string", async () => { + const target = await saml.getLogoutUrlAsync(req, options); + Object.keys(url.parse(target!, true).query).should.have.length(3); + url.parse(target!, true).query["key"]!.should.equal("value"); + url.parse(target!, true).query["SAMLRequest"]!.should.not.be.empty(); + url.parse(target!, true).query["additionalKey"]!.should.equal("additionalValue"); }); // NOTE: This test only tests existence of the assertion, not the correctness - it("calls callback with saml request object", function (done) { - saml.getLogoutUrl(req, {}, function (err, target) { - try { - should(url.parse(target!, true).query).have.property("SAMLRequest"); - done(); - } catch (err2) { - done(err2); - } - }); + it("calls callback with saml request object", async () => { + const target = await saml.getLogoutUrlAsync(req, {}); + should(url.parse(target!, true).query).have.property("SAMLRequest"); }); }); diff --git a/test/strategy.spec.ts b/test/strategy.spec.ts index cdaf4228..411813d1 100644 --- a/test/strategy.spec.ts +++ b/test/strategy.spec.ts @@ -8,8 +8,8 @@ const noop = () => undefined; describe("strategy#authorize", function () { beforeEach(function () { - this.getAuthorizeFormStub = sinon.stub(SAML.prototype, "getAuthorizeForm"); - this.getAuthorizeUrlStub = sinon.stub(SAML.prototype, "getAuthorizeUrl"); + this.getAuthorizeFormStub = sinon.stub(SAML.prototype, "getAuthorizeFormAsync").resolves(); + this.getAuthorizeUrlStub = sinon.stub(SAML.prototype, "getAuthorizeUrlAsync").resolves(); }); afterEach(function () { diff --git a/test/test-signatures.spec.ts b/test/test-signatures.spec.ts index c9f8bcea..8daac061 100644 --- a/test/test-signatures.spec.ts +++ b/test/test-signatures.spec.ts @@ -2,6 +2,7 @@ import { SAML } from "../lib/passport-saml/index.js"; import * as fs from "fs"; import * as sinon from "sinon"; import "should"; +import assert = require("assert"); const cert = fs.readFileSync(__dirname + "/static/cert.pem", "ascii"); @@ -17,29 +18,22 @@ describe("Signatures", function () { done(ex); } }, - testOneResponseBody = ( + testOneResponseBody = async ( samlResponseBody: Record, shouldErrorWith: string | false | undefined, amountOfSignatureChecks = 1 ) => { - return (done: Mocha.Done) => { - //== Instantiate new instance before every test - const samlObj = new SAML({ cert }); - //== Spy on `validateSignature` to be able to count how many times it has been called - const validateSignatureSpy = sinon.spy(samlObj, "validateSignature"); + //== Instantiate new instance before every test + const samlObj = new SAML({ cert }); + //== Spy on `validateSignature` to be able to count how many times it has been called + const validateSignatureSpy = sinon.spy(samlObj, "validateSignature"); - //== Run the test in `func` - samlObj.validatePostResponse( - samlResponseBody, - tryCatchTest(done, function (error: any) { - //== Assert error. If the error is `SAML assertion expired` we made it past the certificate validation - error.should.eql(new Error(shouldErrorWith || "SAML assertion expired")); - //== Assert times `validateSignature` was called - validateSignatureSpy.callCount.should.eql(amountOfSignatureChecks); - done(); - }) - ); - }; + //== Run the test in `func` + await assert.rejects(samlObj.validatePostResponseAsync(samlResponseBody), { + message: shouldErrorWith || "SAML assertion expired", + }); + //== Assert times `validateSignature` was called + validateSignatureSpy.callCount.should.eql(amountOfSignatureChecks); }, testOneResponse = ( pathToXml: string, @@ -47,7 +41,8 @@ describe("Signatures", function () { amountOfSignaturesChecks: number | undefined ) => { //== Create a body based on an XML and run the test - return testOneResponseBody(createBody(pathToXml), shouldErrorWith, amountOfSignaturesChecks); + return async () => + await testOneResponseBody(createBody(pathToXml), shouldErrorWith, amountOfSignaturesChecks); }; describe("Signatures on saml:Response - Only 1 saml:Assertion", () => { @@ -232,14 +227,14 @@ describe("Signatures", function () { .toString(); const makeBody = (str: string) => ({ SAMLResponse: Buffer.from(str).toString("base64") }); - it("CRLF line endings", (done) => { + it("CRLF line endings", async () => { const body = makeBody(samlResponseXml.replace(/\n/g, "\r\n")); - testOneResponseBody(body, false, 1)(done); + await testOneResponseBody(body, false, 1); }); - it("CR line endings", (done) => { + it("CR line endings", async () => { const body = makeBody(samlResponseXml.replace(/\n/g, "\r")); - testOneResponseBody(body, false, 1)(done); + await testOneResponseBody(body, false, 1); }); }); }); diff --git a/test/tests.spec.ts b/test/tests.spec.ts index c19d67d6..253b5e6b 100644 --- a/test/tests.spec.ts +++ b/test/tests.spec.ts @@ -22,6 +22,7 @@ import { } from "../src/passport-saml/types.js"; import * as should from "should"; import { Server } from "http"; +import assert = require("assert"); // a certificate which is re-used by several tests const TEST_CERT = @@ -1762,19 +1763,13 @@ describe("passport-saml /", function () { }); describe("validatePostResponse checks /", function () { - it("response with junk content should explain the XML or base64 is not valid", function (done) { + it("response with junk content should explain the XML or base64 is not valid", async () => { const samlObj = new SAML({ cert: TEST_CERT }); - samlObj.validatePostResponse({ SAMLResponse: "BOOM" }, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/SAMLResponse is not valid base64-encoded XML/); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync({ SAMLResponse: "BOOM" }), { + message: /SAMLResponse is not valid base64-encoded XML/, }); }); - it("response with error status message should generate appropriate error", function (done) { + it("response with error status message should generate appropriate error", async () => { const xml = 'https://idp.testshib.org/idp/shibbolethRequired NameID format not supported'; const base64xml = Buffer.from(xml).toString("base64"); @@ -1782,41 +1777,23 @@ describe("passport-saml /", function () { const samlObj = new SAML({ cert: "-----BEGIN CERTIFICATE-----" + TEST_CERT + "-----END CERTIFICATE-----", }); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/Responder/); - err!.message!.should.match(/Required NameID format not supported/); - // @ts-expect-error adding extra attr to default Error object - should.exist(err.statusXml); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: /Responder.*Required NameID format not supported/, }); }); - it("response with error status code should generate appropriate error", function (done) { + it("response with error status code should generate appropriate error", async () => { const xml = 'https://idp.testshib.org/idp/shibboleth'; const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML({}); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/Responder/); - err!.message!.should.match(/InvalidNameIDPolicy/); - // @ts-expect-error adding extra attr to default Error object - should.exist(err.statusXml); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: /Responder.*InvalidNameIDPolicy/, }); }); - it("accept response with an attributeStatement element without attributeValue", function (done) { + it("accept response with an attributeStatement element without attributeValue", async () => { const fakeClock = sinon.useFakeTimers(Date.parse("2015-08-31T08:55:00+00:00")); const container = { SAMLResponse: fs @@ -1824,23 +1801,14 @@ describe("passport-saml /", function () { .toString("base64"), }; const samlObj = new SAML({}); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.issuer!.should.eql("https://evil-corp.com"); + profile!.nameID!.should.eql("vincent.vega@evil-corp.com"); + should(profile).have.property("evil-corp.egroupid").eql("vincent.vega@evil-corp.com"); + // attributes without attributeValue child should be ignored + should(profile).not.have.property("evilcorp.roles"); - samlObj.validatePostResponse(container, function (err, profile) { - try { - should.not.exist(err); - profile!.issuer!.should.eql("https://evil-corp.com"); - profile!.nameID!.should.eql("vincent.vega@evil-corp.com"); - should(profile).have.property("evil-corp.egroupid").eql("vincent.vega@evil-corp.com"); - // attributes without attributeValue child should be ignored - should(profile).not.have.property("evilcorp.roles"); - - fakeClock.restore(); - - done(); - } catch (err2) { - done(err2); - } - }); + fakeClock.restore(); }); it("removes InResponseTo value if response validation fails", async () => { @@ -1891,7 +1859,7 @@ describe("passport-saml /", function () { entryPoint: "https://app.onelogin.com/trust/saml2/http-post/sso/371755", cert: TEST_CERT, }; - it("valid onelogin xml document should validate", function (done) { + it("valid onelogin xml document should validate", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -1901,18 +1869,12 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(samlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("onelogin xml document with altered assertion should fail", function (done) { + it("onelogin xml document with altered assertion should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -1922,18 +1884,16 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(samlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/Invalid signature/); - done(); - } catch (err2) { - done(err2); - } - }); + try { + await samlObj.validatePostResponseAsync(container); + should.not.exist(true); + } catch (err) { + should.exist(err); + err!.message!.should.match("Invalid signature"); + } }); - it("onelogin xml document with duplicate altered assertion should fail", function (done) { + it("onelogin xml document with duplicate altered assertion should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -1946,18 +1906,16 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(samlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/Invalid signature/); - done(); - } catch (err2) { - done(err2); - } - }); + try { + await samlObj.validatePostResponseAsync(container); + should.not.exist(true); + } catch (err) { + should.exist(err); + err!.message!.should.match(/Invalid signature/); + } }); - it("onelogin xml document with extra unsigned & altered assertion should fail", function (done) { + it("onelogin xml document with extra unsigned & altered assertion should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755ben@subspacesw.com{audience}urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport' + @@ -1968,18 +1926,16 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(samlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/Invalid signature/); - done(); - } catch (err2) { - done(err2); - } - }); + try { + await samlObj.validatePostResponseAsync(container); + should.not.exist(true); + } catch (err) { + should.exist(err); + err!.message!.should.match(/Invalid signature/); + } }); - it("onelogin xml document with extra nexted assertion should fail", function (done) { + it("onelogin xml document with extra nexted assertion should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -1993,18 +1949,16 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(samlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match(/Invalid signature/); - done(); - } catch (err2) { - done(err2); - } - }); + try { + await samlObj.validatePostResponseAsync(container); + should.not.exist(true); + } catch (err) { + should.exist(err); + err!.message!.should.match("Invalid signature"); + } }); - it("multiple certs should validate with one of the certs", function (done) { + it("multiple certs should validate with one of the certs", async () => { const multiCertSamlConfig = { entryPoint: samlConfig.entryPoint, cert: [ALT_TEST_CERT, samlConfig.cert], @@ -2018,18 +1972,11 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(multiCertSamlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("cert as a function should validate with the returned cert", function (done) { + it("cert as a function should validate with the returned cert", async () => { const functionCertSamlConfig: Partial = { entryPoint: samlConfig.entryPoint, cert: function (callback) { @@ -2045,18 +1992,11 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(functionCertSamlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("cert as a function should validate with one of the returned certs", function (done) { + it("cert as a function should validate with one of the returned certs", async () => { const functionMultiCertSamlConfig: Partial = { entryPoint: samlConfig.entryPoint, cert: function (callback) { @@ -2072,18 +2012,11 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(functionMultiCertSamlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("cert as a function should return an error if the cert function returns an error", function (done) { + it("cert as a function should return an error if the cert function returns an error", async () => { const errorToReturn = new Error("test"); const functionErrorCertSamlConfig: Partial = { entryPoint: samlConfig.entryPoint, @@ -2100,17 +2033,16 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML(functionErrorCertSamlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - err!.should.eql(errorToReturn); - done(); - } catch (err2) { - done(err2); - } - }); + try { + await samlObj.validatePostResponseAsync(container); + should.not.exist(true); + } catch (err) { + should.exist(err); + err!.should.eql(errorToReturn); + } }); - it("XML AttributeValue should return object", function (done) { + it("XML AttributeValue should return object", async () => { const nameid_opaque_string = "*******************************"; const nameQualifier = "https://idp.example.org/idp/saml"; const spNameQualifier = "https://sp.example.org/sp/entity"; @@ -2138,20 +2070,17 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML({}); - samlObj.validatePostResponse(container, function (err, profile, logout) { - should.not.exist(err); - const eptid = profile!["urn:oid:1.3.6.1.4.1.5923.1.1.1.10"] as any; - const nameid = eptid["NameID"][0]; - nameid._.should.eql(nameid_opaque_string); - nameid.$.NameQualifier.should.equal(nameQualifier); - nameid.$.SPNameQualifier.should.equal(spNameQualifier); - nameid.$.Format.should.equal(format); - done(); - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + const eptid = profile!["urn:oid:1.3.6.1.4.1.5923.1.1.1.10"] as any; + const nameid = eptid["NameID"][0]; + nameid._.should.eql(nameid_opaque_string); + nameid.$.NameQualifier.should.equal(nameQualifier); + nameid.$.SPNameQualifier.should.equal(spNameQualifier); + nameid.$.Format.should.equal(format); }); }); - it("An undefined value given with an object should still be undefined", function (done) { + it("An undefined value given with an object should still be undefined", async () => { const xml = "" + '' + @@ -2168,11 +2097,8 @@ describe("passport-saml /", function () { const base64xml = Buffer.from(xml).toString("base64"); const container = { SAMLResponse: base64xml }; const samlObj = new SAML({}); - samlObj.validatePostResponse(container, function (err, profile, logout) { - should.not.exist(err); - should(profile!["attributeName"]).be.undefined(); - done(); - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + should(profile!["attributeName"]).be.undefined(); }); }); @@ -2185,7 +2111,7 @@ describe("passport-saml /", function () { fakeClock.restore(); }); - it("acme_tools request signed with sha256", function (done) { + it("acme_tools request signed with sha256", async () => { const samlConfig: Partial = { entryPoint: "https://adfs.acme_tools.com/adfs/ls/", issuer: "acme_tools_com", @@ -2203,21 +2129,15 @@ describe("passport-saml /", function () { samlObj.generateUniqueID = function () { return "12345678901234567890"; }; - samlObj.getAuthorizeUrl({} as express.Request, {}, function (err, authorizeUrl) { - try { - const qry = querystring.parse(url.parse(authorizeUrl).query || ""); - qry.SigAlg?.should.match("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); - qry.Signature?.should.match( - "hel9NaoLU0brY/VhrQsY+lTtuAbTsT/ul6nZ/eVlSMXQRaKn5LTbKadzxmPghX7s4xoHwdah+yZHK/0u4StYSj4b5MKcqbsJapVr2R7H90z8YfGfR2C/G0Gng721YV9Da6VBzKg8Was91zQotgsMpZ9pGX1kPKi6cgFwPwM4NEFugn8AYgXEriNvO5+Q23K/MdBT2bgwRTj2FQCWTuQcgwbyWHXoquHztZ0lbh8UhY5BfQRv7c6D9XPkQEMMQFQeME4PIEg3JnynwFZk5wwhkphMd5nXxau+zt7Nfp4fRm0G8WYnxV1etBnWimwSglZVaSHFYeQBRsC2wvKSiVS8JA==" - ); - qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); - done(); - } catch (err2) { - done(err2); - } - }); + const authorizeUrl = await samlObj.getAuthorizeUrlAsync({} as express.Request, {}); + const qry = querystring.parse(url.parse(authorizeUrl).query || ""); + qry.SigAlg?.should.match("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); + qry.Signature?.should.match( + "hel9NaoLU0brY/VhrQsY+lTtuAbTsT/ul6nZ/eVlSMXQRaKn5LTbKadzxmPghX7s4xoHwdah+yZHK/0u4StYSj4b5MKcqbsJapVr2R7H90z8YfGfR2C/G0Gng721YV9Da6VBzKg8Was91zQotgsMpZ9pGX1kPKi6cgFwPwM4NEFugn8AYgXEriNvO5+Q23K/MdBT2bgwRTj2FQCWTuQcgwbyWHXoquHztZ0lbh8UhY5BfQRv7c6D9XPkQEMMQFQeME4PIEg3JnynwFZk5wwhkphMd5nXxau+zt7Nfp4fRm0G8WYnxV1etBnWimwSglZVaSHFYeQBRsC2wvKSiVS8JA==" + ); + qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); }); - it("acme_tools request signed with sha256 when using privateKey", function (done) { + it("acme_tools request signed with sha256 when using privateKey", async () => { const samlConfig: Partial = { entryPoint: "https://adfs.acme_tools.com/adfs/ls/", issuer: "acme_tools_com", @@ -2235,21 +2155,15 @@ describe("passport-saml /", function () { samlObj.generateUniqueID = function () { return "12345678901234567890"; }; - samlObj.getAuthorizeUrl({} as express.Request, {}, function (err, authorizeUrl) { - try { - const qry = querystring.parse(url.parse(authorizeUrl).query || ""); - qry.SigAlg?.should.match("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); - qry.Signature?.should.match( - "hel9NaoLU0brY/VhrQsY+lTtuAbTsT/ul6nZ/eVlSMXQRaKn5LTbKadzxmPghX7s4xoHwdah+yZHK/0u4StYSj4b5MKcqbsJapVr2R7H90z8YfGfR2C/G0Gng721YV9Da6VBzKg8Was91zQotgsMpZ9pGX1kPKi6cgFwPwM4NEFugn8AYgXEriNvO5+Q23K/MdBT2bgwRTj2FQCWTuQcgwbyWHXoquHztZ0lbh8UhY5BfQRv7c6D9XPkQEMMQFQeME4PIEg3JnynwFZk5wwhkphMd5nXxau+zt7Nfp4fRm0G8WYnxV1etBnWimwSglZVaSHFYeQBRsC2wvKSiVS8JA==" - ); - qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); - done(); - } catch (err2) { - done(err2); - } - }); + const authorizeUrl = await samlObj.getAuthorizeUrlAsync({} as express.Request, {}); + const qry = querystring.parse(url.parse(authorizeUrl).query || ""); + qry.SigAlg?.should.match("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); + qry.Signature?.should.match( + "hel9NaoLU0brY/VhrQsY+lTtuAbTsT/ul6nZ/eVlSMXQRaKn5LTbKadzxmPghX7s4xoHwdah+yZHK/0u4StYSj4b5MKcqbsJapVr2R7H90z8YfGfR2C/G0Gng721YV9Da6VBzKg8Was91zQotgsMpZ9pGX1kPKi6cgFwPwM4NEFugn8AYgXEriNvO5+Q23K/MdBT2bgwRTj2FQCWTuQcgwbyWHXoquHztZ0lbh8UhY5BfQRv7c6D9XPkQEMMQFQeME4PIEg3JnynwFZk5wwhkphMd5nXxau+zt7Nfp4fRm0G8WYnxV1etBnWimwSglZVaSHFYeQBRsC2wvKSiVS8JA==" + ); + qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); }); - it("acme_tools request not signed if missing entry point", function (done) { + it("acme_tools request not signed if missing entry point", async () => { const samlConfig: Partial = { entryPoint: "", issuer: "acme_tools_com", @@ -2269,19 +2183,11 @@ describe("passport-saml /", function () { const request = 'onelogin_samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'; - samlObj.requestToUrl(request, null, "authorize", {}, function (err) { - try { - should.exist(err); - err!.message!.should.eql( - '"entryPoint" config parameter is required for signed messages' - ); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.requestToUrlAsync(request, null, "authorize", {}), { + message: '"entryPoint" config parameter is required for signed messages', }); }); - it("acme_tools request not signed if missing entry point when using privateKey", function (done) { + it("acme_tools request not signed if missing entry point when using privateKey", async () => { const samlConfig: Partial = { entryPoint: "", issuer: "acme_tools_com", @@ -2301,19 +2207,11 @@ describe("passport-saml /", function () { const request = 'onelogin_samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'; - samlObj.requestToUrl(request, null, "authorize", {}, function (err) { - try { - should.exist(err); - err!.message!.should.eql( - '"entryPoint" config parameter is required for signed messages' - ); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.requestToUrlAsync(request, null, "authorize", {}), { + message: '"entryPoint" config parameter is required for signed messages', }); }); - it("acme_tools request signed with sha1", function (done) { + it("acme_tools request signed with sha1", async () => { const samlConfig: Partial = { entryPoint: "https://adfs.acme_tools.com/adfs/ls/", issuer: "acme_tools_com", @@ -2331,21 +2229,15 @@ describe("passport-saml /", function () { samlObj.generateUniqueID = function () { return "12345678901234567890"; }; - samlObj.getAuthorizeUrl({} as express.Request, {}, function (err, authorizeUrl) { - try { - const qry = querystring.parse(url.parse(authorizeUrl).query || ""); - qry.SigAlg?.should.match("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); - qry.Signature?.should.match( - "MeFo+LjufxP5A+sCRwzR/YH/RV6W14aYSFjUdie62JxkI6hDcVhoSZQUJ3wtWMhL59gJj05tTFnXAZRqUQVsavyy41cmUZVeCsat0gaHBQOILXpp9deB0iSJt1EVQTOJkVx8uu2/WYu/bBiH7w2bpwuCf1gJhlqZb/ca3B6yjHSMjnnVfc2LbNPWHpE5464lrs79VjDXf9GQWfrBr95dh3P51IAb7C+77KDWQUl9WfZfyyuEgS83vyZ0UGOxT4AObJ6NOcLs8+iidDdWJJkBaKQev6U+AghCjLQUYOrflivLIIyqATKu2q9PbOse6Phmnxok50+broXSG23+e+742Q==" - ); - qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); - done(); - } catch (err2) { - done(err2); - } - }); + const authorizeUrl = await samlObj.getAuthorizeUrlAsync({} as express.Request, {}); + const qry = querystring.parse(url.parse(authorizeUrl).query || ""); + qry.SigAlg?.should.match("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); + qry.Signature?.should.match( + "MeFo+LjufxP5A+sCRwzR/YH/RV6W14aYSFjUdie62JxkI6hDcVhoSZQUJ3wtWMhL59gJj05tTFnXAZRqUQVsavyy41cmUZVeCsat0gaHBQOILXpp9deB0iSJt1EVQTOJkVx8uu2/WYu/bBiH7w2bpwuCf1gJhlqZb/ca3B6yjHSMjnnVfc2LbNPWHpE5464lrs79VjDXf9GQWfrBr95dh3P51IAb7C+77KDWQUl9WfZfyyuEgS83vyZ0UGOxT4AObJ6NOcLs8+iidDdWJJkBaKQev6U+AghCjLQUYOrflivLIIyqATKu2q9PbOse6Phmnxok50+broXSG23+e+742Q==" + ); + qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); }); - it("acme_tools request signed with sha1 when using privateKey", function (done) { + it("acme_tools request signed with sha1 when using privateKey", async () => { const samlConfig: Partial = { entryPoint: "https://adfs.acme_tools.com/adfs/ls/", issuer: "acme_tools_com", @@ -2363,19 +2255,13 @@ describe("passport-saml /", function () { samlObj.generateUniqueID = function () { return "12345678901234567890"; }; - samlObj.getAuthorizeUrl({} as express.Request, {}, function (err, authorizeUrl) { - try { - const qry = querystring.parse(url.parse(authorizeUrl).query || ""); - qry.SigAlg?.should.match("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); - qry.Signature?.should.match( - "MeFo+LjufxP5A+sCRwzR/YH/RV6W14aYSFjUdie62JxkI6hDcVhoSZQUJ3wtWMhL59gJj05tTFnXAZRqUQVsavyy41cmUZVeCsat0gaHBQOILXpp9deB0iSJt1EVQTOJkVx8uu2/WYu/bBiH7w2bpwuCf1gJhlqZb/ca3B6yjHSMjnnVfc2LbNPWHpE5464lrs79VjDXf9GQWfrBr95dh3P51IAb7C+77KDWQUl9WfZfyyuEgS83vyZ0UGOxT4AObJ6NOcLs8+iidDdWJJkBaKQev6U+AghCjLQUYOrflivLIIyqATKu2q9PbOse6Phmnxok50+broXSG23+e+742Q==" - ); - qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); - done(); - } catch (err2) { - done(err2); - } - }); + const authorizeUrl = await samlObj.getAuthorizeUrlAsync({} as express.Request, {}); + const qry = querystring.parse(url.parse(authorizeUrl).query || ""); + qry.SigAlg?.should.match("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); + qry.Signature?.should.match( + "MeFo+LjufxP5A+sCRwzR/YH/RV6W14aYSFjUdie62JxkI6hDcVhoSZQUJ3wtWMhL59gJj05tTFnXAZRqUQVsavyy41cmUZVeCsat0gaHBQOILXpp9deB0iSJt1EVQTOJkVx8uu2/WYu/bBiH7w2bpwuCf1gJhlqZb/ca3B6yjHSMjnnVfc2LbNPWHpE5464lrs79VjDXf9GQWfrBr95dh3P51IAb7C+77KDWQUl9WfZfyyuEgS83vyZ0UGOxT4AObJ6NOcLs8+iidDdWJJkBaKQev6U+AghCjLQUYOrflivLIIyqATKu2q9PbOse6Phmnxok50+broXSG23+e+742Q==" + ); + qry.customQueryStringParam?.should.match("CustomQueryStringParamValue"); }); }); @@ -2679,7 +2565,7 @@ describe("passport-saml /", function () { should.not.exist(value); }); - it("onelogin xml document without InResponseTo from request should fail", function (done) { + it("onelogin xml document without InResponseTo from request should fail", async () => { const requestId = "_a6fc46be84e1e3cf3c50"; const xml = 'https://app.onelogin.com/saml/metadata/371755' + @@ -2698,15 +2584,8 @@ describe("passport-saml /", function () { const samlObj = new SAML(samlConfig); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:13:09Z")); - - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match("InResponseTo is not valid"); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: "InResponseTo is not valid", }); }); @@ -2887,7 +2766,7 @@ describe("passport-saml /", function () { fakeClock.restore(); }); - it("onelogin xml document with current time after NotBefore time should validate", function (done) { + it("onelogin xml document with current time after NotBefore time should validate", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -2902,18 +2781,11 @@ describe("passport-saml /", function () { fakeClock.restore(); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:13:09Z")); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("onelogin xml document with current time equal to NotBefore (plus default clock skew) time should validate", function (done) { + it("onelogin xml document with current time equal to NotBefore (plus default clock skew) time should validate", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -2928,18 +2800,11 @@ describe("passport-saml /", function () { fakeClock.restore(); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:13:08Z")); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("onelogin xml document with current time before NotBefore time should fail", function (done) { + it("onelogin xml document with current time before NotBefore time should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -2953,19 +2818,12 @@ describe("passport-saml /", function () { // Fake the current date to be after the valid time range fakeClock.restore(); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:13:07Z")); - - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match("SAML assertion not yet valid"); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: "SAML assertion not yet valid", }); }); - it("onelogin xml document with current time equal to NotOnOrAfter (minus default clock skew) time should fail", function (done) { + it("onelogin xml document with current time equal to NotOnOrAfter (minus default clock skew) time should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -2979,19 +2837,12 @@ describe("passport-saml /", function () { // Fake the current date to be after the valid time range fakeClock.restore(); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:19:08Z")); - - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match("SAML assertion expired"); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: "SAML assertion expired", }); }); - it("onelogin xml document with current time after NotOnOrAfter time (minus default clock skew) should fail", function (done) { + it("onelogin xml document with current time after NotOnOrAfter time (minus default clock skew) should fail", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -3005,19 +2856,12 @@ describe("passport-saml /", function () { // Fake the current date to be after the valid time range fakeClock.restore(); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:19:09Z")); - - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match("SAML assertion expired"); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: "SAML assertion expired", }); }); - it("onelogin xml document with current time after NotOnOrAfter time with accepted clock skew equal to -1 should pass", function (done) { + it("onelogin xml document with current time after NotOnOrAfter time with accepted clock skew equal to -1 should pass", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -3038,18 +2882,11 @@ describe("passport-saml /", function () { fakeClock.restore(); fakeClock = sinon.useFakeTimers(Date.parse("2014-05-28T00:20:09Z")); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); - it("onelogin xml document with audience and no AudienceRestriction should not pass", function (done) { + it("onelogin xml document with audience and no AudienceRestriction should not pass", async function () { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -3065,19 +2902,12 @@ describe("passport-saml /", function () { acceptedClockSkewMs: -1, }; const samlObj = new SAML(samlConfig); - - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match("SAML assertion has no AudienceRestriction"); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: "SAML assertion has no AudienceRestriction", }); }); - it("onelogin xml document with audience not matching AudienceRestriction should not pass", function (done) { + it("onelogin xml document with audience not matching AudienceRestriction should not pass", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -3093,19 +2923,12 @@ describe("passport-saml /", function () { acceptedClockSkewMs: -1, }; const samlObj = new SAML(samlConfig); - - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.exist(err); - err!.message!.should.match("SAML assertion audience mismatch"); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostResponseAsync(container), { + message: "SAML assertion audience mismatch", }); }); - it("onelogin xml document with audience matching AudienceRestriction should pass", function (done) { + it("onelogin xml document with audience matching AudienceRestriction should pass", async () => { const xml = 'https://app.onelogin.com/saml/metadata/371755' + 'https://app.onelogin.com/saml/metadata/371755DCnPTQYBb1hKspbe6fg1U3q8xn4=e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==' + @@ -3122,15 +2945,8 @@ describe("passport-saml /", function () { }; const samlObj = new SAML(samlConfig); - samlObj.validatePostResponse(container, function (err, profile, logout) { - try { - should.not.exist(err); - profile!.nameID!.should.startWith("ploer"); - done(); - } catch (err2) { - done(err2); - } - }); + const { profile } = await samlObj.validatePostResponseAsync(container); + profile!.nameID!.should.startWith("ploer"); }); }); }); @@ -3142,82 +2958,57 @@ describe("passport-saml /", function () { }); }); - it("errors if bad xml", function (done) { + it("errors if bad xml", async function () { const body = { SAMLRequest: "asdf", }; - samlObj.validatePostRequest(body, function (err) { - try { - should.exist(err); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostRequestAsync(body), { + message: /Non-whitespace before first tag/, }); }); - it("errors if bad signature", function (done) { + it("errors if bad signature", async () => { const body = { SAMLRequest: fs.readFileSync( __dirname + "/static/logout_request_with_bad_signature.xml", "base64" ), }; - samlObj.validatePostRequest(body, function (err) { - try { - should.exist(err); - err!.should.eql(new Error("Invalid signature on documentElement")); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostRequestAsync(body), { + message: "Invalid signature on documentElement", }); }); - it("returns profile for valid signature", function (done) { + it("returns profile for valid signature", async () => { const body = { SAMLRequest: fs.readFileSync( __dirname + "/static/logout_request_with_good_signature.xml", "base64" ), }; - samlObj.validatePostRequest(body, function (err, profile) { - try { - should.not.exist(err); - profile!.should.eql({ - ID: "pfxd4d369e8-9ea1-780c-aff8-a1d11a9862a1", - issuer: "http://sp.example.com/demo1/metadata.php", - nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7", - nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", - }); - done(); - } catch (err2) { - done(err2); - } + const { profile } = await samlObj.validatePostRequestAsync(body); + profile!.should.eql({ + ID: "pfxd4d369e8-9ea1-780c-aff8-a1d11a9862a1", + issuer: "http://sp.example.com/demo1/metadata.php", + nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7", + nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", }); }); - it("returns profile for valid signature including session index", function (done) { + it("returns profile for valid signature including session index", async () => { const body = { SAMLRequest: fs.readFileSync( __dirname + "/static/logout_request_with_session_index.xml", "base64" ), }; - samlObj.validatePostRequest(body, function (err, profile) { - try { - should.not.exist(err); - profile!.should.eql({ - ID: "pfxd4d369e8-9ea1-780c-aff8-a1d11a9862a1", - issuer: "http://sp.example.com/demo1/metadata.php", - nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7", - nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", - sessionIndex: "1", - }); - done(); - } catch (err2) { - done(err2); - } + const { profile } = await samlObj.validatePostRequestAsync(body); + profile!.should.eql({ + ID: "pfxd4d369e8-9ea1-780c-aff8-a1d11a9862a1", + issuer: "http://sp.example.com/demo1/metadata.php", + nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7", + nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", + sessionIndex: "1", }); }); - it("returns profile for valid signature with encrypted nameID", function (done) { + it("returns profile for valid signature with encrypted nameID", async () => { const samlObj = new SAML({ cert: fs.readFileSync(__dirname + "/static/cert.pem", "ascii"), decryptionPvk: fs.readFileSync(__dirname + "/static/key.pem", "ascii"), @@ -3228,24 +3019,17 @@ describe("passport-saml /", function () { "base64" ), }; - samlObj.validatePostRequest(body, function (err, profile) { - try { - should.not.exist(err); - profile!.should.eql({ - ID: "pfx00cb5227-d9d0-1d4b-bdb2-c7ad6c3c6906", - issuer: "http://sp.example.com/demo1/metadata.php", - nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7", - nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", - sessionIndex: "1", - }); - done(); - } catch (err2) { - done(err2); - } + const { profile } = await samlObj.validatePostRequestAsync(body); + profile!.should.eql({ + ID: "pfx00cb5227-d9d0-1d4b-bdb2-c7ad6c3c6906", + issuer: "http://sp.example.com/demo1/metadata.php", + nameID: "ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7", + nameIDFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", + sessionIndex: "1", }); }); }); - it("validatePostRequest errors for encrypted nameID with wrong decryptionPvk", function (done) { + it("validatePostRequest errors for encrypted nameID with wrong decryptionPvk", async () => { const samlObj = new SAML({ cert: fs.readFileSync(__dirname + "/static/cert.pem", "ascii"), decryptionPvk: fs.readFileSync(__dirname + "/static/acme_tools_com.key", "ascii"), @@ -3256,296 +3040,225 @@ describe("passport-saml /", function () { "base64" ), }; - samlObj.validatePostRequest(body, function (err) { - try { - should.exist(err); - done(); - } catch (err2) { - done(err2); - } + await assert.rejects(samlObj.validatePostRequestAsync(body), { + message: "Encryption block is invalid.", }); - it("errors if bad privateCert to requestToURL", function (done) { - const samlObj = new SAML({ - entryPoint: "foo", - privateCert: - "-----BEGIN CERTIFICATE-----\n" + - "8mvhvrcCOiJ3mjgKNN1F31jOBJuZNmq0U7n9v+Z+3NfyU/0E9jkrnFvm5ks+p8kl\n" + - "BjuBk9RAkazsU9l02XMS/VxOOIifxKC7R9bDtx0hjolYxgqxPIO5s4rmjj0rLzvo\n" + - "vQTTTx/tB5e+hbdx922QSeTjP4DO4ms6cIexcH+ZEUOJ3wXiHToJW83SXLRtwPI9\n" + - "JbWKeS9nWPnzcedbDNZkGtohW5vf32BHuvLsWcl6eFXRSkdX/7+rgpXmDRB7caQ+\n" + - "2SXVY7ORily7LTKg1cFmuKHDzKTGFIp5/GU6dwIDAQABAoIBAArgFQ+Uk4UN4diY\n" + - "gJWCAaQlTVmP0UEHZQt/NmJrc9ZVduuhOP0hH6gF53nREHz5UQb4nXB2Ksa3MtYD\n" + - "Z1vhJcu/T7pvmib4q+Ij6oAmlyeL/xwVY3IUURMxX3tCdPItlk4PEFELKeqQOiIS\n" + - "7B0DYxWfJbMle3c95w5ruYEr2A+fHCKVSlDpg7uPd9VQ6t7bGMZZvc9tDSC1qPXQ\n" + - "Gd/WOMXxi+t/TpyVZ6tOcEekQzAMLmWElUUPx3TJ0ur0Zl2LZ7IvQEXXias4lUHV\n" + - "fnH3akDCMmdhlJSVqUfplrh85zAOh6fLloZagphj/Kpgfw1TZ+njSDYqSLYE0NZ1\n" + - "j+83feECgYEA2aNGgbc+t6QLrJJ63l9Mz541lVV3IUAxZ5ACqOnMkQVuLoa5IMwM\n" + - "oENIo38ptfHQqjQ9x8/tEINFqOHnQuOJ/+1xP9f0Me+0clRDCqjGYqNYgmakKyD7\n" + - "vey/q6kwHk679RVGiI1p+HdoA+CbEKWHJiRxE0RhAA3G3wGAq7kpJocCgYEAxp4/\n" + - "tCft+eHVRivspfDN//axc2TR6qWP9E1ueGvbiXPXv0Puag0W9cER/df/s5jW4Rqg\n" + - "CE8649HPUZ0FJT+YaeKgu2Sw9SMcGl4/uyHzg7KnXIeYyQZJPqQkKyXmIix8cw3+\n" + - "HBGRtwX5nOy0DgFdaMiH0F08peNI9QHKKTBoWJECgYEAyymJ1ekzWMaAR1Zt8EvS\n" + - "LjWoG4EuthFwjRZ4BSpLVk1Vb4VAKAeS+cAVfNpmG3xip6Ag0/ebe0CvtFk9QsmZ\n" + - "txj2EP0M7div/9H8y2SF3OpS41fhhIlDtyXcPuivDHu/Jaf4sdwgwlrk9EmlN0Lu\n" + - "CIMYMz4vtpclwGNss+EjMt0CgYEAqepD0Vm/iuCaVhfJsgSaFvnywSdlNfpBdtyv\n" + - "PzH2dFa4IZZ55hwgoklznNgmlnyQh68BbVpqpO+fDtDnz//h4ePRYb84a96Hcj9j\n" + - "AjJ/YxF5f/04xfEsw/wkPQ2FHYM1TDCSTWzyXcMs0gTl3H1qbfPvzF+XPMt+ZKwN\n" + - "SMNy4SECgYB3ig6t+XVfNkw8oBOh0Gx37XKbmImXsA8ucDAX9KUbMIvD03XCEf34\n" + - "jF3SNJh0SmHoT62vc+cJqPxMDP6E7Q1nZxsEyaAkKr2H4dSM4SlRm0VB+bS+jXsz\n" + - "PCiRGSm8eupuxfix05LMMreo4mC7e3Ir4JhdCsXxAMZIvbNyXcvUMA==\n" + - "-----END CERTIFICATE-----\n", - }); - const request = - 'onelogin_samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'; - samlObj.requestToUrl(request, null, "authorize", {}, function (err) { - try { - should.exist(err); - err!.message.should.containEql("no start line"); - done(); - } catch (err2) { - done(err2); - } - }); + }); + it("errors if bad privateCert to requestToURL", async () => { + const samlObj = new SAML({ + entryPoint: "foo", + privateCert: + "-----BEGIN CERTIFICATE-----\n" + + "8mvhvrcCOiJ3mjgKNN1F31jOBJuZNmq0U7n9v+Z+3NfyU/0E9jkrnFvm5ks+p8kl\n" + + "BjuBk9RAkazsU9l02XMS/VxOOIifxKC7R9bDtx0hjolYxgqxPIO5s4rmjj0rLzvo\n" + + "vQTTTx/tB5e+hbdx922QSeTjP4DO4ms6cIexcH+ZEUOJ3wXiHToJW83SXLRtwPI9\n" + + "JbWKeS9nWPnzcedbDNZkGtohW5vf32BHuvLsWcl6eFXRSkdX/7+rgpXmDRB7caQ+\n" + + "2SXVY7ORily7LTKg1cFmuKHDzKTGFIp5/GU6dwIDAQABAoIBAArgFQ+Uk4UN4diY\n" + + "gJWCAaQlTVmP0UEHZQt/NmJrc9ZVduuhOP0hH6gF53nREHz5UQb4nXB2Ksa3MtYD\n" + + "Z1vhJcu/T7pvmib4q+Ij6oAmlyeL/xwVY3IUURMxX3tCdPItlk4PEFELKeqQOiIS\n" + + "7B0DYxWfJbMle3c95w5ruYEr2A+fHCKVSlDpg7uPd9VQ6t7bGMZZvc9tDSC1qPXQ\n" + + "Gd/WOMXxi+t/TpyVZ6tOcEekQzAMLmWElUUPx3TJ0ur0Zl2LZ7IvQEXXias4lUHV\n" + + "fnH3akDCMmdhlJSVqUfplrh85zAOh6fLloZagphj/Kpgfw1TZ+njSDYqSLYE0NZ1\n" + + "j+83feECgYEA2aNGgbc+t6QLrJJ63l9Mz541lVV3IUAxZ5ACqOnMkQVuLoa5IMwM\n" + + "oENIo38ptfHQqjQ9x8/tEINFqOHnQuOJ/+1xP9f0Me+0clRDCqjGYqNYgmakKyD7\n" + + "vey/q6kwHk679RVGiI1p+HdoA+CbEKWHJiRxE0RhAA3G3wGAq7kpJocCgYEAxp4/\n" + + "tCft+eHVRivspfDN//axc2TR6qWP9E1ueGvbiXPXv0Puag0W9cER/df/s5jW4Rqg\n" + + "CE8649HPUZ0FJT+YaeKgu2Sw9SMcGl4/uyHzg7KnXIeYyQZJPqQkKyXmIix8cw3+\n" + + "HBGRtwX5nOy0DgFdaMiH0F08peNI9QHKKTBoWJECgYEAyymJ1ekzWMaAR1Zt8EvS\n" + + "LjWoG4EuthFwjRZ4BSpLVk1Vb4VAKAeS+cAVfNpmG3xip6Ag0/ebe0CvtFk9QsmZ\n" + + "txj2EP0M7div/9H8y2SF3OpS41fhhIlDtyXcPuivDHu/Jaf4sdwgwlrk9EmlN0Lu\n" + + "CIMYMz4vtpclwGNss+EjMt0CgYEAqepD0Vm/iuCaVhfJsgSaFvnywSdlNfpBdtyv\n" + + "PzH2dFa4IZZ55hwgoklznNgmlnyQh68BbVpqpO+fDtDnz//h4ePRYb84a96Hcj9j\n" + + "AjJ/YxF5f/04xfEsw/wkPQ2FHYM1TDCSTWzyXcMs0gTl3H1qbfPvzF+XPMt+ZKwN\n" + + "SMNy4SECgYB3ig6t+XVfNkw8oBOh0Gx37XKbmImXsA8ucDAX9KUbMIvD03XCEf34\n" + + "jF3SNJh0SmHoT62vc+cJqPxMDP6E7Q1nZxsEyaAkKr2H4dSM4SlRm0VB+bS+jXsz\n" + + "PCiRGSm8eupuxfix05LMMreo4mC7e3Ir4JhdCsXxAMZIvbNyXcvUMA==\n" + + "-----END CERTIFICATE-----\n", }); - it("errors if bad privateKey to requestToURL", function (done) { - const samlObj = new SAML({ - entryPoint: "foo", - privateKey: - "-----BEGIN CERTIFICATE-----\n" + - "8mvhvrcCOiJ3mjgKNN1F31jOBJuZNmq0U7n9v+Z+3NfyU/0E9jkrnFvm5ks+p8kl\n" + - "BjuBk9RAkazsU9l02XMS/VxOOIifxKC7R9bDtx0hjolYxgqxPIO5s4rmjj0rLzvo\n" + - "vQTTTx/tB5e+hbdx922QSeTjP4DO4ms6cIexcH+ZEUOJ3wXiHToJW83SXLRtwPI9\n" + - "JbWKeS9nWPnzcedbDNZkGtohW5vf32BHuvLsWcl6eFXRSkdX/7+rgpXmDRB7caQ+\n" + - "2SXVY7ORily7LTKg1cFmuKHDzKTGFIp5/GU6dwIDAQABAoIBAArgFQ+Uk4UN4diY\n" + - "gJWCAaQlTVmP0UEHZQt/NmJrc9ZVduuhOP0hH6gF53nREHz5UQb4nXB2Ksa3MtYD\n" + - "Z1vhJcu/T7pvmib4q+Ij6oAmlyeL/xwVY3IUURMxX3tCdPItlk4PEFELKeqQOiIS\n" + - "7B0DYxWfJbMle3c95w5ruYEr2A+fHCKVSlDpg7uPd9VQ6t7bGMZZvc9tDSC1qPXQ\n" + - "Gd/WOMXxi+t/TpyVZ6tOcEekQzAMLmWElUUPx3TJ0ur0Zl2LZ7IvQEXXias4lUHV\n" + - "fnH3akDCMmdhlJSVqUfplrh85zAOh6fLloZagphj/Kpgfw1TZ+njSDYqSLYE0NZ1\n" + - "j+83feECgYEA2aNGgbc+t6QLrJJ63l9Mz541lVV3IUAxZ5ACqOnMkQVuLoa5IMwM\n" + - "oENIo38ptfHQqjQ9x8/tEINFqOHnQuOJ/+1xP9f0Me+0clRDCqjGYqNYgmakKyD7\n" + - "vey/q6kwHk679RVGiI1p+HdoA+CbEKWHJiRxE0RhAA3G3wGAq7kpJocCgYEAxp4/\n" + - "tCft+eHVRivspfDN//axc2TR6qWP9E1ueGvbiXPXv0Puag0W9cER/df/s5jW4Rqg\n" + - "CE8649HPUZ0FJT+YaeKgu2Sw9SMcGl4/uyHzg7KnXIeYyQZJPqQkKyXmIix8cw3+\n" + - "HBGRtwX5nOy0DgFdaMiH0F08peNI9QHKKTBoWJECgYEAyymJ1ekzWMaAR1Zt8EvS\n" + - "LjWoG4EuthFwjRZ4BSpLVk1Vb4VAKAeS+cAVfNpmG3xip6Ag0/ebe0CvtFk9QsmZ\n" + - "txj2EP0M7div/9H8y2SF3OpS41fhhIlDtyXcPuivDHu/Jaf4sdwgwlrk9EmlN0Lu\n" + - "CIMYMz4vtpclwGNss+EjMt0CgYEAqepD0Vm/iuCaVhfJsgSaFvnywSdlNfpBdtyv\n" + - "PzH2dFa4IZZ55hwgoklznNgmlnyQh68BbVpqpO+fDtDnz//h4ePRYb84a96Hcj9j\n" + - "AjJ/YxF5f/04xfEsw/wkPQ2FHYM1TDCSTWzyXcMs0gTl3H1qbfPvzF+XPMt+ZKwN\n" + - "SMNy4SECgYB3ig6t+XVfNkw8oBOh0Gx37XKbmImXsA8ucDAX9KUbMIvD03XCEf34\n" + - "jF3SNJh0SmHoT62vc+cJqPxMDP6E7Q1nZxsEyaAkKr2H4dSM4SlRm0VB+bS+jXsz\n" + - "PCiRGSm8eupuxfix05LMMreo4mC7e3Ir4JhdCsXxAMZIvbNyXcvUMA==\n" + - "-----END CERTIFICATE-----\n", - }); - const request = - 'onelogin_samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'; - samlObj.requestToUrl(request, null, "authorize", {}, function (err) { - try { - should.exist(err); - err!.message!.should.containEql("no start line"); - done(); - } catch (err2) { - done(err2); - } - }); + const request = + 'onelogin_samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'; + await assert.rejects(samlObj.requestToUrlAsync(request, null, "authorize", {}), { + message: /no start line/, + }); + }); + it("errors if bad privateKey to requestToURL", async () => { + const samlObj = new SAML({ + entryPoint: "foo", + privateKey: + "-----BEGIN CERTIFICATE-----\n" + + "8mvhvrcCOiJ3mjgKNN1F31jOBJuZNmq0U7n9v+Z+3NfyU/0E9jkrnFvm5ks+p8kl\n" + + "BjuBk9RAkazsU9l02XMS/VxOOIifxKC7R9bDtx0hjolYxgqxPIO5s4rmjj0rLzvo\n" + + "vQTTTx/tB5e+hbdx922QSeTjP4DO4ms6cIexcH+ZEUOJ3wXiHToJW83SXLRtwPI9\n" + + "JbWKeS9nWPnzcedbDNZkGtohW5vf32BHuvLsWcl6eFXRSkdX/7+rgpXmDRB7caQ+\n" + + "2SXVY7ORily7LTKg1cFmuKHDzKTGFIp5/GU6dwIDAQABAoIBAArgFQ+Uk4UN4diY\n" + + "gJWCAaQlTVmP0UEHZQt/NmJrc9ZVduuhOP0hH6gF53nREHz5UQb4nXB2Ksa3MtYD\n" + + "Z1vhJcu/T7pvmib4q+Ij6oAmlyeL/xwVY3IUURMxX3tCdPItlk4PEFELKeqQOiIS\n" + + "7B0DYxWfJbMle3c95w5ruYEr2A+fHCKVSlDpg7uPd9VQ6t7bGMZZvc9tDSC1qPXQ\n" + + "Gd/WOMXxi+t/TpyVZ6tOcEekQzAMLmWElUUPx3TJ0ur0Zl2LZ7IvQEXXias4lUHV\n" + + "fnH3akDCMmdhlJSVqUfplrh85zAOh6fLloZagphj/Kpgfw1TZ+njSDYqSLYE0NZ1\n" + + "j+83feECgYEA2aNGgbc+t6QLrJJ63l9Mz541lVV3IUAxZ5ACqOnMkQVuLoa5IMwM\n" + + "oENIo38ptfHQqjQ9x8/tEINFqOHnQuOJ/+1xP9f0Me+0clRDCqjGYqNYgmakKyD7\n" + + "vey/q6kwHk679RVGiI1p+HdoA+CbEKWHJiRxE0RhAA3G3wGAq7kpJocCgYEAxp4/\n" + + "tCft+eHVRivspfDN//axc2TR6qWP9E1ueGvbiXPXv0Puag0W9cER/df/s5jW4Rqg\n" + + "CE8649HPUZ0FJT+YaeKgu2Sw9SMcGl4/uyHzg7KnXIeYyQZJPqQkKyXmIix8cw3+\n" + + "HBGRtwX5nOy0DgFdaMiH0F08peNI9QHKKTBoWJECgYEAyymJ1ekzWMaAR1Zt8EvS\n" + + "LjWoG4EuthFwjRZ4BSpLVk1Vb4VAKAeS+cAVfNpmG3xip6Ag0/ebe0CvtFk9QsmZ\n" + + "txj2EP0M7div/9H8y2SF3OpS41fhhIlDtyXcPuivDHu/Jaf4sdwgwlrk9EmlN0Lu\n" + + "CIMYMz4vtpclwGNss+EjMt0CgYEAqepD0Vm/iuCaVhfJsgSaFvnywSdlNfpBdtyv\n" + + "PzH2dFa4IZZ55hwgoklznNgmlnyQh68BbVpqpO+fDtDnz//h4ePRYb84a96Hcj9j\n" + + "AjJ/YxF5f/04xfEsw/wkPQ2FHYM1TDCSTWzyXcMs0gTl3H1qbfPvzF+XPMt+ZKwN\n" + + "SMNy4SECgYB3ig6t+XVfNkw8oBOh0Gx37XKbmImXsA8ucDAX9KUbMIvD03XCEf34\n" + + "jF3SNJh0SmHoT62vc+cJqPxMDP6E7Q1nZxsEyaAkKr2H4dSM4SlRm0VB+bS+jXsz\n" + + "PCiRGSm8eupuxfix05LMMreo4mC7e3Ir4JhdCsXxAMZIvbNyXcvUMA==\n" + + "-----END CERTIFICATE-----\n", + }); + const request = + 'onelogin_samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'; + await assert.rejects(samlObj.requestToUrlAsync(request, null, "authorize", {}), { + message: /no start line/, }); }); +}); - describe("validateRedirect()", function () { - describe("idp slo", function () { - let samlObj: SAML; - beforeEach(function () { - samlObj = new SAML({ - cert: fs.readFileSync(__dirname + "/static/acme_tools_com.cert", "ascii"), - idpIssuer: "http://localhost:20000/saml2/idp/metadata.php", - }); - this.request = Object.assign( - {}, - JSON.parse(fs.readFileSync(__dirname + "/static/idp_slo_redirect.json", "utf8")) - ); - this.clock = sinon.useFakeTimers(Date.parse("2018-04-11T14:08:00Z")); - }); - afterEach(function () { - this.clock.restore(); - }); - it("errors if bad xml", function (done) { - const body = { - SAMLRequest: "asdf", - }; - samlObj.validateRedirect(body, this.request.originalQuery, function (err) { - try { - should.exist(err); - done(); - } catch (err2) { - done(err2); - } - }); - }); - it("errors if idpIssuer is set and issuer is wrong", function (done) { - samlObj.options.idpIssuer = "foo"; - samlObj.validateRedirect(this.request, this.request.originalQuery, function (err) { - try { - should.exist(err); - err!.message!.should.eql( - "Unknown SAML issuer. Expected: foo Received: http://localhost:20000/saml2/idp/metadata.php" - ); - done(); - } catch (err2) { - done(err2); - } - }); - }); - it("errors if request has expired", function (done) { - this.clock.restore(); - samlObj.validateRedirect(this.request, this.request.originalQuery, function (err) { - try { - should.exist(err); - err!.message!.should.eql("SAML assertion expired"); - done(); - } catch (err2) { - done(err2); - } - }); - }); - it("errors if request has a bad signature", function (done) { - this.request.Signature = "foo"; - samlObj.validateRedirect( - this.request, - this.request.originalQuery, - function (err: Error | null) { - try { - should.exist(err); - err!.message!.should.eql("Invalid signature"); - done(); - } catch (err2) { - done(err2); - } - } - ); - }); - it("returns profile for valid signature including session index", function (done) { - samlObj.validateRedirect(this.request, this.request.originalQuery, function (err, profile) { - try { - should.not.exist(err); - profile!.should.eql({ - ID: "_8f0effde308adfb6ae7f1e29b414957fc320f5636f", - issuer: "http://localhost:20000/saml2/idp/metadata.php", - nameID: "stavros@workable.com", - nameIDFormat: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", - sessionIndex: "_00bf7b2d5d9d3c970217eecefb1194bef3362a618e", - }); - done(); - } catch (err2) { - done(err2); - } - }); +describe("validateRedirect()", function () { + describe("idp slo", function () { + let samlObj: SAML; + beforeEach(function () { + samlObj = new SAML({ + cert: fs.readFileSync(__dirname + "/static/acme_tools_com.cert", "ascii"), + idpIssuer: "http://localhost:20000/saml2/idp/metadata.php", }); + this.request = Object.assign( + {}, + JSON.parse(fs.readFileSync(__dirname + "/static/idp_slo_redirect.json", "utf8")) + ); + this.clock = sinon.useFakeTimers(Date.parse("2018-04-11T14:08:00Z")); }); - describe("sp slo", function () { - let samlObj: SAML; - beforeEach(function () { - samlObj = new SAML({ - cert: fs.readFileSync(__dirname + "/static/acme_tools_com.cert", "ascii"), - idpIssuer: "http://localhost:20000/saml2/idp/metadata.php", - validateInResponseTo: true, - }); - this.request = Object.assign( - {}, - JSON.parse(fs.readFileSync(__dirname + "/static/sp_slo_redirect.json", "utf8")) - ); - this.clock = sinon.useFakeTimers(Date.parse("2018-04-11T14:08:00Z")); - }); - afterEach(async function () { - this.clock.restore(); - await samlObj.cacheProvider.removeAsync("_79db1e7ad12ca1d63e5b"); - }); - it("errors if bad xml", function (done) { - const body = { - SAMLRequest: "asdf", - }; - samlObj.validateRedirect(body, null, function (err) { - try { - should.exist(err); - done(); - } catch (err2) { - done(err2); - } - }); - }); - it("errors if idpIssuer is set and wrong issuer", function (done) { - samlObj.options.idpIssuer = "foo"; - samlObj.validateRedirect(this.request, this.request.originalQuery, function (err) { - try { - should.exist(err); - err!.message!.should.eql( - "Unknown SAML issuer. Expected: foo Received: http://localhost:20000/saml2/idp/metadata.php" - ); - done(); - } catch (err2) { - done(err2); - } - }); - }); - it("errors if unsuccessful", function (done) { - this.request = JSON.parse( - fs.readFileSync(__dirname + "/static/sp_slo_redirect_failure.json", "utf8") - ); - samlObj.validateRedirect(this.request, this.request.originalQuery, function (err) { - try { - should.exist(err); - err!.message!.should.eql( - "Bad status code: urn:oasis:names:tc:SAML:2.0:status:Requester" - ); - done(); - } catch (err2) { - done(err2); - } - }); + afterEach(function () { + this.clock.restore(); + }); + it("errors if bad xml", async function () { + const body = { + SAMLRequest: "asdf", + }; + await assert.rejects(samlObj.validateRedirectAsync(body, this.request.originalQuery)); + }); + it("errors if idpIssuer is set and issuer is wrong", async function () { + samlObj.options.idpIssuer = "foo"; + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { + message: + "Unknown SAML issuer. Expected: foo Received: http://localhost:20000/saml2/idp/metadata.php", + } + ); + }); + it("errors if request has expired", async function () { + this.clock.restore(); + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { message: "SAML assertion expired" } + ); + }); + it("errors if request has a bad signature", async function () { + this.request.Signature = "foo"; + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { message: "Invalid signature" } + ); + }); + it("returns profile for valid signature including session index", async function () { + const { profile } = await samlObj.validateRedirectAsync( + this.request, + this.request.originalQuery + ); + profile!.should.eql({ + ID: "_8f0effde308adfb6ae7f1e29b414957fc320f5636f", + issuer: "http://localhost:20000/saml2/idp/metadata.php", + nameID: "stavros@workable.com", + nameIDFormat: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", + sessionIndex: "_00bf7b2d5d9d3c970217eecefb1194bef3362a618e", }); - it("errors if InResponseTo is not found", function (done) { - samlObj.validateRedirect(this.request, this.request.originalQuery, function (err) { - try { - should.exist(err); - err!.message!.should.eql("InResponseTo is not valid"); - done(); - } catch (err2) { - done(err2); - } - }); + }); + }); + describe("sp slo", function () { + let samlObj: SAML; + beforeEach(function () { + samlObj = new SAML({ + cert: fs.readFileSync(__dirname + "/static/acme_tools_com.cert", "ascii"), + idpIssuer: "http://localhost:20000/saml2/idp/metadata.php", + validateInResponseTo: true, }); - it("errors if bad signature", async function () { - await samlObj.cacheProvider.saveAsync("_79db1e7ad12ca1d63e5b", new Date().toISOString()); - this.request.Signature = "foo"; - try { - await samlObj.validateRedirectAsync(this.request, this.request.originalQuery); - } catch (err) { - should.exist(err); - err!.message!.should.eql("Invalid signature"); + this.request = Object.assign( + {}, + JSON.parse(fs.readFileSync(__dirname + "/static/sp_slo_redirect.json", "utf8")) + ); + this.clock = sinon.useFakeTimers(Date.parse("2018-04-11T14:08:00Z")); + }); + afterEach(async function () { + this.clock.restore(); + await samlObj.cacheProvider.removeAsync("_79db1e7ad12ca1d63e5b"); + }); + it("errors if bad xml", async function () { + const body = { + SAMLRequest: "asdf", + }; + await assert.rejects(samlObj.validateRedirectAsync(body, null)); + }); + it("errors if idpIssuer is set and wrong issuer", async function () { + samlObj.options.idpIssuer = "foo"; + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { + message: + "Unknown SAML issuer. Expected: foo Received: http://localhost:20000/saml2/idp/metadata.php", } - }); + ); + }); + it("errors if unsuccessful", async function () { + this.request = JSON.parse( + fs.readFileSync(__dirname + "/static/sp_slo_redirect_failure.json", "utf8") + ); + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { message: "Bad status code: urn:oasis:names:tc:SAML:2.0:status:Requester" } + ); + }); + it("errors if InResponseTo is not found", async function () { + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { message: "InResponseTo is not valid" } + ); + }); + it("errors if bad signature", async function () { + await samlObj.cacheProvider.saveAsync("_79db1e7ad12ca1d63e5b", new Date().toISOString()); + this.request.Signature = "foo"; + await assert.rejects( + samlObj.validateRedirectAsync(this.request, this.request.originalQuery), + { message: "Invalid signature" } + ); + }); - it("returns true for valid signature", async function () { - await samlObj.cacheProvider.saveAsync("_79db1e7ad12ca1d63e5b", new Date().toISOString()); - const { loggedOut } = await samlObj.validateRedirectAsync( - this.request, - this.request.originalQuery - ); - loggedOut!.should.eql(true); - }); + it("returns true for valid signature", async function () { + await samlObj.cacheProvider.saveAsync("_79db1e7ad12ca1d63e5b", new Date().toISOString()); + const { loggedOut } = await samlObj.validateRedirectAsync( + this.request, + this.request.originalQuery + ); + loggedOut!.should.eql(true); + }); - it("accepts cert without header and footer line", async function () { - samlObj.options.cert = fs.readFileSync( - __dirname + "/static/acme_tools_com_without_header_and_footer.cert", - "ascii" - ); - await samlObj.cacheProvider.saveAsync("_79db1e7ad12ca1d63e5b", new Date().toISOString()); - const { loggedOut } = await samlObj.validateRedirectAsync( - this.request, - this.request.originalQuery - ); - loggedOut!.should.eql(true); - }); + it("accepts cert without header and footer line", async function () { + samlObj.options.cert = fs.readFileSync( + __dirname + "/static/acme_tools_com_without_header_and_footer.cert", + "ascii" + ); + await samlObj.cacheProvider.saveAsync("_79db1e7ad12ca1d63e5b", new Date().toISOString()); + const { loggedOut } = await samlObj.validateRedirectAsync( + this.request, + this.request.originalQuery + ); + loggedOut!.should.eql(true); }); }); });