|
async getAuthorizeUrlAsync( |
|
RelayState: string, |
|
host: string | undefined, |
|
options: AuthOptions, |
|
): Promise<string> { |
|
const request = await this.generateAuthorizeRequestAsync(this.options.passive, false); |
|
const operation = "authorize"; |
|
const overrideParams = options ? options.additionalParams || {} : {}; |
|
return await this._requestToUrlAsync( |
|
request, |
|
null, |
|
operation, |
|
this._getAdditionalParams(RelayState, operation, overrideParams), |
|
); |
|
} |
|
|
|
async getAuthorizeMessageAsync( |
|
RelayState: string, |
|
host?: string, |
|
options?: AuthOptions, |
|
): Promise<querystring.ParsedUrlQueryInput> { |
|
assertRequired(this.options.entryPoint, "entryPoint is required"); |
|
|
|
const request = await this.generateAuthorizeRequestAsync(this.options.passive, true); |
|
let buffer: Buffer; |
|
if (this.options.skipRequestCompression) { |
|
buffer = Buffer.from(request, "utf8"); |
|
} else { |
|
buffer = await deflateRawAsync(request); |
|
} |
|
|
|
const operation = "authorize"; |
|
const overrideParams = options ? options.additionalParams || {} : {}; |
|
const additionalParameters = this._getAdditionalParams(RelayState, operation, overrideParams); |
|
const samlMessage: querystring.ParsedUrlQueryInput = { |
|
SAMLRequest: buffer.toString("base64"), |
|
}; |
|
|
|
Object.keys(additionalParameters).forEach((k) => { |
|
samlMessage[k] = additionalParameters[k] || ""; |
|
}); |
|
|
|
return samlMessage; |
|
} |
|
|
|
async getAuthorizeFormAsync( |
|
RelayState: string, |
|
host?: string, |
|
options?: AuthOptions, |
|
): Promise<string> { |
|
assertRequired(this.options.entryPoint, "entryPoint is required"); |
|
|
|
// 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 |
|
// of an element attribute. |
|
const quoteattr = function ( |
|
s: |
|
| string |
|
| number |
|
| boolean |
|
| undefined |
|
| null |
|
| readonly string[] |
|
| readonly number[] |
|
| readonly boolean[], |
|
preserveCR?: boolean, |
|
) { |
|
const preserveCRChar = preserveCR ? " " : "\n"; |
|
return ( |
|
("" + s) // Forces the conversion to string. |
|
.replace(/&/g, "&") // This MUST be the 1st replacement. |
|
.replace(/'/g, "'") // The 4 other predefined entities, required. |
|
.replace(/"/g, """) |
|
.replace(/</g, "<") |
|
.replace(/>/g, ">") |
|
// Add other replacements here for HTML only |
|
// Or for XML, only if the named entities are defined in its DTD. |
|
.replace(/\r\n/g, preserveCRChar) // Must be before the next replacement. |
|
.replace(/[\r\n]/g, preserveCRChar) |
|
); |
|
}; |
|
|
|
const samlMessage = await this.getAuthorizeMessageAsync(RelayState, host, options); |
|
|
|
const formInputs = Object.keys(samlMessage) |
|
.map((k) => { |
|
return '<input type="hidden" name="' + k + '" value="' + quoteattr(samlMessage[k]) + '" />'; |
|
}) |
|
.join("\r\n"); |
|
|
|
return [ |
|
"<!DOCTYPE html>", |
|
"<html>", |
|
"<head>", |
|
'<meta charset="utf-8">', |
|
'<meta http-equiv="x-ua-compatible" content="ie=edge">', |
|
"</head>", |
|
'<body onload="document.forms[0].submit()">', |
|
"<noscript>", |
|
"<p><strong>Note:</strong> Since your browser does not support JavaScript, you must press the button below once to proceed.</p>", |
|
"</noscript>", |
|
'<form method="post" action="' + encodeURI(this.options.entryPoint) + '">', |
|
formInputs, |
|
'<input type="submit" value="Submit" />', |
|
"</form>", |
|
'<script>document.forms[0].style.display="none";</script>', // Hide the form if JavaScript is enabled |
|
"</body>", |
|
"</html>", |
|
].join("\r\n"); |
|
} |
hostparameter is just confusing and since it isn't used it should be removed in next major versionnode-saml/src/saml.ts
Lines 514 to 623 in 0d3d3fa