File: C:/Windows/SystemApps/Microsoft.Windows.CloudExperienceHost_cw5n1h2txyewy/js/msaUIHandler.js
//
// Copyright (C) Microsoft. All rights reserved.
//
/// <disable>JS2085.EnableStrictMode, JS2055.DoNotReferenceBannedTerms</disable>
"use strict";
var CloudExperienceHost;
(function (CloudExperienceHost) {
var Crypto = Windows.Security.Cryptography;
class MSAUIHandlerInternal {
constructor(appView, tokenOperation) {
this._webAppTelemetry = CloudExperienceHost.Telemetry.WebAppTelemetry.getInstance();
if (!this._webAppTelemetry.isStarted()) {
this._webAppTelemetry.start("msaUIHandler");
}
this._appView = appView;
this._registerNgcOperation = null;
this._tokenBrokerOperation = tokenOperation; // Passed by tokenProviderManager
WinJS.Namespace.define("CloudExperienceHost.MSAUIHandler", {
saveAuthenticationState: this.saveAuthenticationState.bind(this),
saveAuthStateAndCompleteWebFlow: this.saveAuthStateAndCompleteWebFlow.bind(this),
getVerificationCode: this.getVerificationCode.bind(this),
updateLogonCache: this.updateLogonCache.bind(this),
completeWebFlow: this.completeWebFlow.bind(this)
});
}
getTokenOperation() {
return this._tokenBrokerOperation;
}
clearTokenBrokerOperation() {
// This should only be called when there is a new ticket request coming from postTicketToReturnUrl.
if (this._tokenBrokerOperation != null) {
let target = this._tokenBrokerOperation.webFlowRequest ? this._tokenBrokerOperation.webFlowRequest.url : "";
let policy = this._tokenBrokerOperation.webFlowRequest ? this._tokenBrokerOperation.webFlowRequest.policy : "";
this._webAppTelemetry.logEvent("ResetTokenBrokerOperation", JSON.stringify({
target: target, policy: policy
}));
this._tokenBrokerOperation = null;
}
}
_buildTicketRequest(target, policy, onComplete, onError) {
// Set PostTicketToUrlOperation
let webFlowRequest;
webFlowRequest = new MicrosoftAccount.TokenProvider.Core.PostTicketToUrlOperation();
webFlowRequest.url = target;
webFlowRequest.policy = policy;
webFlowRequest.onComplete = onComplete;
webFlowRequest.onError = onError;
webFlowRequest.isRequestTicketForUrlScenario = false;
// Set TokenProviderOperation
let tokenOperation;
let user = null;
user = CloudExperienceHost.IUserManager.getInstance().getIUser();
tokenOperation = new MicrosoftAccount.TokenProvider.Core.TokenBrokerOperation(user);
tokenOperation.isRequestFromWebFlow = true;
tokenOperation.wasUserPrompted = true;
tokenOperation.webFlowRequest = webFlowRequest;
return tokenOperation;
}
requestTicketForUrl(data, msaTicketContext, navigate) {
return new WinJS.Promise(function (completeDispatch, errorDispatch /*, progressDispatch */) {
this._appView.showProgress().then(function () {
this._webAppTelemetry.logEvent("postTicketToReturnUrl");
if (this._tokenBrokerOperation) {
// Concurrent WAM operations are banned. Return ERROR_OPERATION_IN_PROGRESS
errorDispatch({ number: -2147024567 });
return;
}
var tokenOperation;
tokenOperation = this._buildTicketRequest(data.targetUrl, data.policy,
// On success, navigate to target
function (returnUrl, result) {
this._tokenBrokerOperation = null;
completeDispatch(new CloudExperienceHost.RedirectEventArgs(returnUrl, null, result, result ? "POST" : "GET"));
}.bind(this),
// On failure, invoke parent error handler in a manner consistent with exceptions.
function (error) {
this._tokenBrokerOperation = null;
errorDispatch({ number: error });
}.bind(this));
this._tokenBrokerOperation = tokenOperation;
tokenOperation.wasUserPrompted = true;
tokenOperation.loadUrlInWebView = navigate;
tokenOperation.webFlowRequest.isRequestTicketForUrlScenario = true;
if (msaTicketContext) {
tokenOperation.scenarioId = msaTicketContext;
}
let user = CloudExperienceHost.IUserManager.getInstance().getIUser();
if (user === null) {
tokenOperation.useBroker = data.msaTicketBroker;
}
// Request ticket
var executor;
executor = new MicrosoftAccount.TokenProvider.Core.TokenProviderExecutor(tokenOperation);
executor.requestTicketForUrl();
}.bind(this));
}.bind(this));
}
requestLPTForUser(data, msaTicketContext, experienceName, navigate) {
return new WinJS.Promise(function (completeDispatch, errorDispatch /*, progressDispatch */) {
this._appView.showProgress().then(function () {
let userId = CloudExperienceHost.IUserManager.getInstance().getUserId();
if (this._registerNgcOperation) {
// Concurrent NGC operations are banned. Return ERROR_OPERATION_IN_PROGRESS
this._webAppTelemetry.logEvent("concurrentNgcRequest", JSON.stringify({
correlationId: this._webAppTelemetry.getId()
}));
errorDispatch({ number: -2147024567 });
return;
}
this._webAppTelemetry.logEvent("requestLPTForUser", JSON.stringify({
returnUrl: data.returnUrl,
useStrongAuth: data.useStrongAuth,
useBroker: data.msaTicketBroker ? true : false,
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
userId: userId
}));
var purpose = data.useStrongAuth == true ? "PURPOSE_KEYREGISTER" : "PURPOSE_KEYREGISTER_WEAK";
var tokenOperation;
tokenOperation = this._buildTicketRequest("http://passport.net/purpose", purpose,
// On success, return LPT
function (ignoredUrl, logonProofToken) {
this._registerNgcOperation = null;
this._webAppTelemetry.logEvent("requestLPTForUser", JSON.stringify({
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
hr: 0,
userId: userId
}));
completeDispatch(logonProofToken);
}.bind(this),
// On failure, invoke parent error handler in a manner consistent with exceptions.
function (error) {
this._registerNgcOperation = null;
this._webAppTelemetry.logEvent("requestLPTForUser", JSON.stringify({
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
hr: error,
userId: userId
}));
let destinationUrl = this._appendErrorCodeToUrl(data.returnUrl, error);
errorDispatch(destinationUrl);
}.bind(this));
this._registerNgcOperation = tokenOperation;
tokenOperation.wasUserPrompted = true;
tokenOperation.loadUrlInWebView = navigate;
if (msaTicketContext) {
tokenOperation.scenarioId = msaTicketContext;
}
let user = CloudExperienceHost.IUserManager.getInstance().getIUser();
if (user === null) {
tokenOperation.useBroker = data.msaTicketBroker;
}
// Request ticket
var executor;
executor = new MicrosoftAccount.TokenProvider.Core.TokenProviderExecutor(tokenOperation);
executor.requestLPTForUser(data.puid || "", data.username || "", data.flowToken || "");
}.bind(this));
}.bind(this));
}
registerNGCForUser(data, msaTicketContext, experienceName, navigate) {
return new WinJS.Promise(function (completeDispatch, /* _onTicketRequestComplete */ errorDispatch /*, progressDispatch */) {
this.requestLPTForUser(data, msaTicketContext, experienceName, navigate).done(function (logonProofToken) {
// Create NGC
var extension = new MicrosoftAccount.UserOperations.ExtensionForUser();
let user = null;
user = CloudExperienceHost.IUserManager.getInstance().getIUser();
let logonProofTokenBuffer = null;
if (logonProofToken) {
logonProofTokenBuffer = Crypto.CryptographicBuffer.convertStringToBinary(logonProofToken, Crypto.BinaryStringEncoding.utf8);
}
let setChromeDimBasedOnFocus = (CloudExperienceHost.getContext().personality === CloudExperienceHost.TargetPersonality.LiteWhite);
let isTransparencyOptionSetOnCredUICoordinator = false;
if (setChromeDimBasedOnFocus) {
// hide UI for transparent CredUI
this._appView.setChromeDimBasedOnFocus(setChromeDimBasedOnFocus);
isTransparencyOptionSetOnCredUICoordinator = CloudExperienceHost.CredUI.setTransparencyOptionOnCredUICoordinator();
}
// Prime Ngc logon cache is required if it's NoPa or Federated MSA.
// If PIN is registered from the lock screen (i.e. WindowsLogon scenario), make the priming Ngc logon cache operation synchronously
// to avoid missing the logon cache due to the termination of the runtimebroker.exe.
let requirePrimeNgcLogonCache = (data.isNoPassword == true || msaTicketContext === "WindowsLogon");
extension.createUserIdKeyForUserAsync(user, data.useStrongAuth, requirePrimeNgcLogonCache, data.username || "", data.puid || "", logonProofTokenBuffer).done(function (hResult) {
if (setChromeDimBasedOnFocus) {
this._appView.setChromeDimBasedOnFocus(false);
if (isTransparencyOptionSetOnCredUICoordinator) {
CloudExperienceHost.CredUI.removeTransparencyOptionOnCredUICoordinator();
}
}
// Finish
this._webAppTelemetry.logEvent("registerNGCForUser", JSON.stringify({
useStrongAuth: data.useStrongAuth,
isNoPassword: (data.isNoPassword == true),
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
hr: hResult
}));
// Do not append the hResult in PIN enrollment since server need to create a new page in OOBE if prime Ngc logon cache fail.
completeDispatch(data.returnUrl);
}.bind(this), function (error) {
if (setChromeDimBasedOnFocus) {
this._appView.setChromeDimBasedOnFocus(false);
if (isTransparencyOptionSetOnCredUICoordinator) {
CloudExperienceHost.CredUI.removeTransparencyOptionOnCredUICoordinator();
}
}
// Error for createUserIdkeyAsync
this._webAppTelemetry.logEvent("registerNGCForUser", JSON.stringify({
useStrongAuth: data.useStrongAuth,
isNoPassword: (data.isNoPassword == true),
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
hr: error.number
}));
let destinationUrl = this._appendErrorCodeToUrl(data.returnUrl, error.number);
errorDispatch(destinationUrl);
}.bind(this));
}.bind(this), errorDispatch /* Error for requestLPTForUser */);
}.bind(this));
}
resetNGCForUser(data, msaTicketContext, experienceName, navigate) {
return new WinJS.Promise(function (completeDispatch, /* _onTicketRequestComplete */ errorDispatch /*, progressDispatch */) {
this.requestLPTForUser(data, msaTicketContext, experienceName, navigate).done(function (logonProofToken) {
// Reset NGC
var extension = new MicrosoftAccount.Extension.ExtensionWorkerForUser();
let user = null;
user = CloudExperienceHost.IUserManager.getInstance().getIUser();
let logonProofTokenBuffer = null;
if (logonProofToken) {
logonProofTokenBuffer = Crypto.CryptographicBuffer.convertStringToBinary(logonProofToken, Crypto.BinaryStringEncoding.utf8);
}
extension.resetUserIdKeyForUserAsync(user, data.useStrongAuth, data.isNoPassword == true, msaTicketContext, data.username || "", data.puid || "", logonProofTokenBuffer).done(function (hResult) {
// Finish
this._webAppTelemetry.logEvent("resetNGCForUser", JSON.stringify({
useStrongAuth: data.useStrongAuth,
isNoPassword: (data.isNoPassword == true),
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
hr: hResult
}));
let destinationUrl = this._appendErrorCodeToUrl(data.returnUrl, hResult);
completeDispatch(destinationUrl);
}.bind(this), function (error) {
// Error for resetUserIdkeyAsync
this._webAppTelemetry.logEvent("resetNGCForUser", JSON.stringify({
useStrongAuth: data.useStrongAuth,
isNoPassword: (data.isNoPassword == true),
experienceName: experienceName,
correlationId: this._webAppTelemetry.getId(),
hr: error.number
}));
let destinationUrl = this._appendErrorCodeToUrl(data.returnUrl, error.number);
errorDispatch(destinationUrl);
}.bind(this));
}.bind(this), errorDispatch /* Error for requestLPTForUser */);
}.bind(this));
}
updateLogonCache(requestId, puid, encryptedPassword) {
}
getVerificationCode() {
let verificationCode = null;
if (this._tokenBrokerOperation) {
verificationCode = this._tokenBrokerOperation.receivedVerificationCode;
}
else {
verificationCode = CloudExperienceHost.MSA.getVerificationCode();
}
if ((typeof (verificationCode) === 'undefined') ||
verificationCode == "") {
verificationCode = null;
}
return verificationCode;
}
saveAuthenticationState(data) {
let tokenOperation = this._registerNgcOperation || this._tokenBrokerOperation;
let dataFromWeb = new MicrosoftAccount.TokenProvider.Core.WebFlowResultData();
let daTokenBuffer = null;
if (data.daToken) {
daTokenBuffer = Crypto.CryptographicBuffer.convertStringToBinary(data.daToken, Crypto.BinaryStringEncoding.utf8);
}
let sessionKeyBuffer = null;
if (data.sessionKey) {
sessionKeyBuffer = Crypto.CryptographicBuffer.decodeFromBase64String(data.sessionKey);
}
dataFromWeb.daTokenBuffer = daTokenBuffer;
dataFromWeb.sessionKeyBuffer = sessionKeyBuffer;
dataFromWeb.sessionKeyType = data.sessionKeyType || "";
dataFromWeb.daTokenCreationTime = data.daTokenCreationTime || "";
dataFromWeb.daTokenExpiryTime = data.daTokenExpiryTime || "";
dataFromWeb.puid = data.puid || "";
dataFromWeb.username = data.username || "";
dataFromWeb.isCompleteWebFlow = false;
tokenOperation.wasUserPrompted = true;
var msaTokenProvider;
msaTokenProvider = new MicrosoftAccount.TokenProvider.Core.TokenProviderExecutor(tokenOperation);
return msaTokenProvider.saveAuthenticationState(dataFromWeb);
}
saveAuthStateAndCompleteWebFlow(status, requestId, puid, username, daToken, daTokenCreationTime, daTokenExpiryTime, sessionKey, flowToken, hr, hrInternal, sessionKeyType) {
this._webAppTelemetry.logEvent("saveAuthStateAndCompleteWebFlow", hr);
var tokenOperation = this._registerNgcOperation || this._tokenBrokerOperation;
if (!tokenOperation) {
this._webAppTelemetry.logEvent("undefinedTokenOperation");
// The unhandled exception handler in tokenProviderManager calls this function, so throwing would cause infinite recursion.
// The TokenProvider error handler page calls this function on "OK", so that would cause an infinite loop.
// Nothing we can do here if the caller was WAM.
return;
}
this._appView.showProgress().then(function () {
if (tokenOperation.stopListeningForVerificationCode != null) {
// This will not exist in non-Token Broker flows. In those cases, we don't have to worry about cancelling anyway.
tokenOperation.stopListeningForVerificationCode();
}
tokenOperation.wasUserPrompted = true;
var msaTokenProvider;
msaTokenProvider = new MicrosoftAccount.TokenProvider.Core.TokenProviderExecutor(tokenOperation);
if (this._isUndefined("status", status) === true) {
msaTokenProvider.failAuthentication("0xc0000163", "0xc0000163"); // 0xc0000163 - TYPE_E_UNDEFINEDTYPE
this._webAppTelemetry.logEvent("saveAuthStateAndCompleteStatus", "0xc0000163");
return;
}
if (status == CloudExperienceHost.AppResult.success) {
let dataFromWeb = new MicrosoftAccount.TokenProvider.Core.WebFlowResultData();
let daTokenBuffer = null;
if (daToken) {
daTokenBuffer = Crypto.CryptographicBuffer.convertStringToBinary(daToken, Crypto.BinaryStringEncoding.utf8);
}
let sessionKeyBuffer = null;
if (sessionKey) {
sessionKeyBuffer = Crypto.CryptographicBuffer.decodeFromBase64String(sessionKey);
}
dataFromWeb.daTokenBuffer = daTokenBuffer;
dataFromWeb.sessionKeyBuffer = sessionKeyBuffer;
dataFromWeb.sessionKeyType = sessionKeyType;
dataFromWeb.daTokenCreationTime = daTokenCreationTime;
dataFromWeb.daTokenExpiryTime = daTokenExpiryTime;
dataFromWeb.flowToken = flowToken;
dataFromWeb.puid = puid;
dataFromWeb.username = username;
dataFromWeb.isCompleteWebFlow = false;
msaTokenProvider.resumeAuthentication(dataFromWeb);
}
else {
if (this._isUndefined("hr", hr) === true) {
hr = "0xc0000163"; // STATUS_UNDEFINED_CHARACTER
}
let HRESULT_ONL_E_REQUEST_THROTTLED = "0X80860010";
if ((hr !== null) && (hr.toUpperCase() === HRESULT_ONL_E_REQUEST_THROTTLED)) {
msaTokenProvider.restartAuthentication();
}
else {
msaTokenProvider.failAuthentication(hr, hrInternal);
this._isUndefined("hrInternal", hrInternal);
}
}
this._webAppTelemetry.logEvent("saveAuthStateAndCompleteStatus", JSON.stringify(status));
}.bind(this));
}
completeWebFlow(data) {
this._webAppTelemetry.logEvent("completeWebFlow", JSON.stringify(data.hr));
let tokenOperation = this._registerNgcOperation || this._tokenBrokerOperation;
if (!tokenOperation) {
this._webAppTelemetry.logEvent("undefinedTokenOperation");
// The unhandled exception handler in tokenProviderManager calls this function, so throwing would cause infinite recursion.
// The TokenProvider error handler page calls this function on "OK", so that would cause an infinite loop.
// Nothing we can do here if the caller was WAM.
return;
}
tokenOperation.wasUserPrompted = true;
this._appView.showProgress().then(function () {
if (tokenOperation.stopListeningForVerificationCode != null) {
// This will not exist in non-Token Broker flows. In those cases, we don't have to worry about cancelling anyway.
tokenOperation.stopListeningForVerificationCode();
}
let msaTokenProvider;
msaTokenProvider = new MicrosoftAccount.TokenProvider.Core.TokenProviderExecutor(tokenOperation);
let dataFromWeb = new MicrosoftAccount.TokenProvider.Core.WebFlowResultData();
dataFromWeb.flowToken = data.flowToken || "";
dataFromWeb.puid = data.puid || "";
dataFromWeb.username = data.username || "";
dataFromWeb.isCompleteWebFlow = true;
if (data.hr.toLowerCase() == "0x0") {
if (data.completeRequest === true) {
msaTokenProvider.completeAuthentication(dataFromWeb);
}
else {
msaTokenProvider.resumeAuthentication(dataFromWeb);
}
}
else {
msaTokenProvider.failAuthentication(data.hr, data.hrInternal);
}
this._webAppTelemetry.logEvent("completeWebFlow done");
}.bind(this));
}
_isUndefined(paramName, param) {
if ((typeof (param) === 'undefined')) {
this._webAppTelemetry.logEvent("isUndefined", paramName);
return true;
}
return false;
}
_appendErrorCodeToUrl(url, errorCode) {
if (errorCode !== 0) {
let hexString = "0x" + (errorCode < 0 ? errorCode + 0x100000000 /* 32-bit signed -> unsigned conversion; 2^32 */ : errorCode).toString(16);
url += (url.indexOf('?') > 0 ? '&' : '?') + "errorCode=" + encodeURIComponent(hexString);
}
return url;
}
}
CloudExperienceHost.MSAUIHandlerInternal = MSAUIHandlerInternal;
})(CloudExperienceHost || (CloudExperienceHost = {}));
//# sourceMappingURL=msauihandler.js.map