const require_rolldown_runtime = require('../../../../_virtual/rolldown_runtime.cjs');
const require_utility$1 = require('./utility.cjs');
const require_urn$1 = require('./urn.cjs');
const require_extractor$1 = require('./extractor.cjs');
const require_libsaml$1 = require('./libsaml.cjs');
const require_validator$1 = require('./validator.cjs');

//#region ../../node_modules/samlify/build/src/flow.js
var require_flow = /* @__PURE__ */ require_rolldown_runtime.__commonJS({ "../../node_modules/samlify/build/src/flow.js": ((exports) => {
	var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
		function adopt(value) {
			return value instanceof P ? value : new P(function(resolve) {
				resolve(value);
			});
		}
		return new (P || (P = Promise))(function(resolve, reject) {
			function fulfilled(value) {
				try {
					step(generator.next(value));
				} catch (e) {
					reject(e);
				}
			}
			function rejected(value) {
				try {
					step(generator["throw"](value));
				} catch (e) {
					reject(e);
				}
			}
			function step(result) {
				result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
			}
			step((generator = generator.apply(thisArg, _arguments || [])).next());
		});
	};
	var __generator = exports && exports.__generator || function(thisArg, body) {
		var _ = {
			label: 0,
			sent: function() {
				if (t[0] & 1) throw t[1];
				return t[1];
			},
			trys: [],
			ops: []
		}, f, y, t, g;
		return g = {
			next: verb(0),
			"throw": verb(1),
			"return": verb(2)
		}, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
			return this;
		}), g;
		function verb(n) {
			return function(v) {
				return step([n, v]);
			};
		}
		function step(op) {
			if (f) throw new TypeError("Generator is already executing.");
			while (_) try {
				if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
				if (y = 0, t) op = [op[0] & 2, t.value];
				switch (op[0]) {
					case 0:
					case 1:
						t = op;
						break;
					case 4:
						_.label++;
						return {
							value: op[1],
							done: false
						};
					case 5:
						_.label++;
						y = op[1];
						op = [0];
						continue;
					case 7:
						op = _.ops.pop();
						_.trys.pop();
						continue;
					default:
						if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
							_ = 0;
							continue;
						}
						if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
							_.label = op[1];
							break;
						}
						if (op[0] === 6 && _.label < t[1]) {
							_.label = t[1];
							t = op;
							break;
						}
						if (t && _.label < t[2]) {
							_.label = t[2];
							_.ops.push(op);
							break;
						}
						if (t[2]) _.ops.pop();
						_.trys.pop();
						continue;
				}
				op = body.call(thisArg, _);
			} catch (e) {
				op = [6, e];
				y = 0;
			} finally {
				f = t = 0;
			}
			if (op[0] & 5) throw op[1];
			return {
				value: op[0] ? op[1] : void 0,
				done: true
			};
		}
	};
	var __read = exports && exports.__read || function(o, n) {
		var m = typeof Symbol === "function" && o[Symbol.iterator];
		if (!m) return o;
		var i = m.call(o), r, ar = [], e;
		try {
			while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
		} catch (error) {
			e = { error };
		} finally {
			try {
				if (r && !r.done && (m = i["return"])) m.call(i);
			} finally {
				if (e) throw e.error;
			}
		}
		return ar;
	};
	var __importDefault = exports && exports.__importDefault || function(mod) {
		return mod && mod.__esModule ? mod : { "default": mod };
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	exports.flow = void 0;
	var utility_1 = require_utility$1.default;
	var validator_1 = require_validator$1.default;
	var libsaml_1 = __importDefault(require_libsaml$1.default);
	var extractor_1 = require_extractor$1.default;
	var urn_1 = require_urn$1.default;
	var bindDict = urn_1.wording.binding;
	var urlParams = urn_1.wording.urlParams;
	function getDefaultExtractorFields(parserType, assertion) {
		switch (parserType) {
			case urn_1.ParserType.SAMLRequest: return extractor_1.loginRequestFields;
			case urn_1.ParserType.SAMLResponse:
				if (!assertion) throw new Error("ERR_EMPTY_ASSERTION");
				return (0, extractor_1.loginResponseFields)(assertion);
			case urn_1.ParserType.LogoutRequest: return extractor_1.logoutRequestFields;
			case urn_1.ParserType.LogoutResponse: return extractor_1.logoutResponseFields;
			default: throw new Error("ERR_UNDEFINED_PARSERTYPE");
		}
	}
	function redirectFlow(options) {
		return __awaiter(this, void 0, void 0, function() {
			var request, parserType, self, _a, checkSignature, from, query, octetString, sigAlg, signature, targetEntityMetadata, direction, content, xmlString, assertion, verifiedDoc, extractorFields, parseResult, base64Signature, decodeSigAlg, verified, issuer, extractedProperties;
			return __generator(this, function(_b) {
				switch (_b.label) {
					case 0:
						request = options.request, parserType = options.parserType, self = options.self, _a = options.checkSignature, checkSignature = _a === void 0 ? true : _a, from = options.from;
						query = request.query, octetString = request.octetString;
						sigAlg = query.SigAlg, signature = query.Signature;
						targetEntityMetadata = from.entityMeta;
						direction = libsaml_1.default.getQueryParamByType(parserType);
						content = query[direction];
						if (content === void 0) return [2, Promise.reject("ERR_REDIRECT_FLOW_BAD_ARGS")];
						xmlString = (0, utility_1.inflateString)(decodeURIComponent(content));
						_b.label = 1;
					case 1:
						_b.trys.push([
							1,
							3,
							,
							4
						]);
						return [4, libsaml_1.default.isValidXml(xmlString)];
					case 2:
						_b.sent();
						return [3, 4];
					case 3:
						_b.sent();
						return [2, Promise.reject("ERR_INVALID_XML")];
					case 4: return [4, checkStatus(xmlString, parserType)];
					case 5:
						_b.sent();
						assertion = "";
						if (parserType === urlParams.samlResponse) {
							verifiedDoc = (0, extractor_1.extract)(xmlString, [{
								key: "assertion",
								localPath: ["~Response", "Assertion"],
								attributes: [],
								context: true
							}]);
							if (verifiedDoc && verifiedDoc.assertion) assertion = verifiedDoc.assertion;
						}
						extractorFields = getDefaultExtractorFields(parserType, assertion.length > 0 ? assertion : null);
						parseResult = {
							samlContent: xmlString,
							sigAlg: null,
							extract: (0, extractor_1.extract)(xmlString, extractorFields)
						};
						if (checkSignature) {
							if (!signature || !sigAlg) return [2, Promise.reject("ERR_MISSING_SIG_ALG")];
							base64Signature = Buffer.from(decodeURIComponent(signature), "base64");
							decodeSigAlg = decodeURIComponent(sigAlg);
							verified = libsaml_1.default.verifyMessageSignature(targetEntityMetadata, octetString, base64Signature, sigAlg);
							if (!verified) return [2, Promise.reject("ERR_FAILED_MESSAGE_SIGNATURE_VERIFICATION")];
							parseResult.sigAlg = decodeSigAlg;
						}
						issuer = targetEntityMetadata.getEntityID();
						extractedProperties = parseResult.extract;
						if ((parserType === "LogoutResponse" || parserType === "SAMLResponse") && extractedProperties && extractedProperties.issuer !== issuer) return [2, Promise.reject("ERR_UNMATCH_ISSUER")];
						if (parserType === "SAMLResponse" && extractedProperties.sessionIndex.sessionNotOnOrAfter && !(0, validator_1.verifyTime)(void 0, extractedProperties.sessionIndex.sessionNotOnOrAfter, self.entitySetting.clockDrifts)) return [2, Promise.reject("ERR_EXPIRED_SESSION")];
						if (parserType === "SAMLResponse" && extractedProperties.conditions && !(0, validator_1.verifyTime)(extractedProperties.conditions.notBefore, extractedProperties.conditions.notOnOrAfter, self.entitySetting.clockDrifts)) return [2, Promise.reject("ERR_SUBJECT_UNCONFIRMED")];
						return [2, Promise.resolve(parseResult)];
				}
			});
		});
	}
	function postFlow(options) {
		return __awaiter(this, void 0, void 0, function() {
			var request, from, self, parserType, _a, checkSignature, body, direction, encodedRequest, samlContent, verificationOptions, decryptRequired, extractorFields, _b, verified, verifiedAssertionNode, result, result, decryptedDoc, _c, decryptedDocVerified, verifiedDecryptedAssertion, parseResult, targetEntityMetadata, issuer, extractedProperties;
			return __generator(this, function(_d) {
				switch (_d.label) {
					case 0:
						request = options.request, from = options.from, self = options.self, parserType = options.parserType, _a = options.checkSignature, checkSignature = _a === void 0 ? true : _a;
						body = request.body;
						direction = libsaml_1.default.getQueryParamByType(parserType);
						encodedRequest = body[direction];
						samlContent = String((0, utility_1.base64Decode)(encodedRequest));
						verificationOptions = {
							metadata: from.entityMeta,
							signatureAlgorithm: from.entitySetting.requestSignatureAlgorithm
						};
						decryptRequired = from.entitySetting.isAssertionEncrypted;
						extractorFields = [];
						return [4, libsaml_1.default.isValidXml(samlContent)];
					case 1:
						_d.sent();
						if (parserType !== urlParams.samlResponse) extractorFields = getDefaultExtractorFields(parserType, null);
						return [4, checkStatus(samlContent, parserType)];
					case 2:
						_d.sent();
						if (!checkSignature) return [3, 7];
						_b = __read(libsaml_1.default.verifySignature(samlContent, verificationOptions), 2), verified = _b[0], verifiedAssertionNode = _b[1];
						if (!(decryptRequired && verified && parserType === "SAMLResponse" && verifiedAssertionNode)) return [3, 4];
						return [4, libsaml_1.default.decryptAssertion(self, verifiedAssertionNode)];
					case 3:
						result = _d.sent();
						samlContent = result[0];
						extractorFields = getDefaultExtractorFields(parserType, result[1]);
						return [3, 7];
					case 4:
						if (!(decryptRequired && !verified)) return [3, 6];
						return [4, libsaml_1.default.decryptAssertion(self, samlContent)];
					case 5:
						result = _d.sent();
						decryptedDoc = result[0];
						_c = __read(libsaml_1.default.verifySignature(decryptedDoc, verificationOptions), 2), decryptedDocVerified = _c[0], verifiedDecryptedAssertion = _c[1];
						if (decryptedDocVerified) extractorFields = getDefaultExtractorFields(parserType, verifiedDecryptedAssertion);
						else return [2, Promise.reject("FAILED_TO_VERIFY_SIGNATURE")];
						return [3, 7];
					case 6:
						if (verified) extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
						else return [2, Promise.reject("FAILED_TO_VERIFY_SIGNATURE")];
						_d.label = 7;
					case 7:
						parseResult = {
							samlContent,
							extract: (0, extractor_1.extract)(samlContent, extractorFields)
						};
						targetEntityMetadata = from.entityMeta;
						issuer = targetEntityMetadata.getEntityID();
						extractedProperties = parseResult.extract;
						if ((parserType === "LogoutResponse" || parserType === "SAMLResponse") && extractedProperties && extractedProperties.issuer !== issuer) return [2, Promise.reject("ERR_UNMATCH_ISSUER")];
						if (parserType === "SAMLResponse" && extractedProperties.sessionIndex.sessionNotOnOrAfter && !(0, validator_1.verifyTime)(void 0, extractedProperties.sessionIndex.sessionNotOnOrAfter, self.entitySetting.clockDrifts)) return [2, Promise.reject("ERR_EXPIRED_SESSION")];
						if (parserType === "SAMLResponse" && extractedProperties.conditions && !(0, validator_1.verifyTime)(extractedProperties.conditions.notBefore, extractedProperties.conditions.notOnOrAfter, self.entitySetting.clockDrifts)) return [2, Promise.reject("ERR_SUBJECT_UNCONFIRMED")];
						return [2, Promise.resolve(parseResult)];
				}
			});
		});
	}
	function postSimpleSignFlow(options) {
		return __awaiter(this, void 0, void 0, function() {
			var request, parserType, self, _a, checkSignature, from, body, octetString, targetEntityMetadata, direction, encodedRequest, sigAlg, signature, xmlString, assertion, verifiedDoc, extractorFields, parseResult, base64Signature, verified, issuer, extractedProperties;
			return __generator(this, function(_b) {
				switch (_b.label) {
					case 0:
						request = options.request, parserType = options.parserType, self = options.self, _a = options.checkSignature, checkSignature = _a === void 0 ? true : _a, from = options.from;
						body = request.body, octetString = request.octetString;
						targetEntityMetadata = from.entityMeta;
						direction = libsaml_1.default.getQueryParamByType(parserType);
						encodedRequest = body[direction];
						sigAlg = body["SigAlg"];
						signature = body["Signature"];
						if (encodedRequest === void 0) return [2, Promise.reject("ERR_SIMPLESIGN_FLOW_BAD_ARGS")];
						xmlString = String((0, utility_1.base64Decode)(encodedRequest));
						_b.label = 1;
					case 1:
						_b.trys.push([
							1,
							3,
							,
							4
						]);
						return [4, libsaml_1.default.isValidXml(xmlString)];
					case 2:
						_b.sent();
						return [3, 4];
					case 3:
						_b.sent();
						return [2, Promise.reject("ERR_INVALID_XML")];
					case 4: return [4, checkStatus(xmlString, parserType)];
					case 5:
						_b.sent();
						assertion = "";
						if (parserType === urlParams.samlResponse) {
							verifiedDoc = (0, extractor_1.extract)(xmlString, [{
								key: "assertion",
								localPath: ["~Response", "Assertion"],
								attributes: [],
								context: true
							}]);
							if (verifiedDoc && verifiedDoc.assertion) assertion = verifiedDoc.assertion;
						}
						extractorFields = getDefaultExtractorFields(parserType, assertion.length > 0 ? assertion : null);
						parseResult = {
							samlContent: xmlString,
							sigAlg: null,
							extract: (0, extractor_1.extract)(xmlString, extractorFields)
						};
						if (checkSignature) {
							if (!signature || !sigAlg) return [2, Promise.reject("ERR_MISSING_SIG_ALG")];
							base64Signature = Buffer.from(signature, "base64");
							verified = libsaml_1.default.verifyMessageSignature(targetEntityMetadata, octetString, base64Signature, sigAlg);
							if (!verified) return [2, Promise.reject("ERR_FAILED_MESSAGE_SIGNATURE_VERIFICATION")];
							parseResult.sigAlg = sigAlg;
						}
						issuer = targetEntityMetadata.getEntityID();
						extractedProperties = parseResult.extract;
						if ((parserType === "LogoutResponse" || parserType === "SAMLResponse") && extractedProperties && extractedProperties.issuer !== issuer) return [2, Promise.reject("ERR_UNMATCH_ISSUER")];
						if (parserType === "SAMLResponse" && extractedProperties.sessionIndex.sessionNotOnOrAfter && !(0, validator_1.verifyTime)(void 0, extractedProperties.sessionIndex.sessionNotOnOrAfter, self.entitySetting.clockDrifts)) return [2, Promise.reject("ERR_EXPIRED_SESSION")];
						if (parserType === "SAMLResponse" && extractedProperties.conditions && !(0, validator_1.verifyTime)(extractedProperties.conditions.notBefore, extractedProperties.conditions.notOnOrAfter, self.entitySetting.clockDrifts)) return [2, Promise.reject("ERR_SUBJECT_UNCONFIRMED")];
						return [2, Promise.resolve(parseResult)];
				}
			});
		});
	}
	function checkStatus(content, parserType) {
		if (parserType !== urlParams.samlResponse && parserType !== urlParams.logoutResponse) return Promise.resolve("SKIPPED");
		var fields = parserType === urlParams.samlResponse ? extractor_1.loginResponseStatusFields : extractor_1.logoutResponseStatusFields;
		var _a = (0, extractor_1.extract)(content, fields), top = _a.top, second = _a.second;
		if (top === urn_1.StatusCode.Success) return Promise.resolve("OK");
		if (!top) throw new Error("ERR_UNDEFINED_STATUS");
		throw new Error("ERR_FAILED_STATUS with top tier code: ".concat(top, ", second tier code: ").concat(second));
	}
	function flow(options) {
		var binding = options.binding;
		var parserType = options.parserType;
		options.supportBindings = [
			urn_1.BindingNamespace.Redirect,
			urn_1.BindingNamespace.Post,
			urn_1.BindingNamespace.SimpleSign
		];
		if (parserType === urn_1.ParserType.SAMLResponse) options.supportBindings = [
			urn_1.BindingNamespace.Post,
			urn_1.BindingNamespace.Redirect,
			urn_1.BindingNamespace.SimpleSign
		];
		if (binding === bindDict.post) return postFlow(options);
		if (binding === bindDict.redirect) return redirectFlow(options);
		if (binding === bindDict.simpleSign) return postSimpleSignFlow(options);
		return Promise.reject("ERR_UNEXPECTED_FLOW");
	}
	exports.flow = flow;
}) });

//#endregion
Object.defineProperty(exports, 'default', {
  enumerable: true,
  get: function () {
    return require_flow();
  }
});
//# sourceMappingURL=flow.cjs.map