Merge branch 'v8/8.9' into v8/dev
# Conflicts: # src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
This commit is contained in:
@@ -13,7 +13,10 @@
|
||||
}
|
||||
});
|
||||
|
||||
function UmbLoginController($scope, $location, currentUserResource, formHelper, mediaHelper, umbRequestHelper, Upload, localizationService, userService, externalLoginInfo, resetPasswordCodeInfo, $timeout, authResource, $q, $route) {
|
||||
function UmbLoginController($scope, $location, currentUserResource, formHelper,
|
||||
mediaHelper, umbRequestHelper, Upload, localizationService,
|
||||
userService, externalLoginInfo, externalLoginInfoService,
|
||||
resetPasswordCodeInfo, $timeout, authResource, $q, $route) {
|
||||
|
||||
const vm = this;
|
||||
|
||||
@@ -43,7 +46,15 @@
|
||||
vm.allowPasswordReset = Umbraco.Sys.ServerVariables.umbracoSettings.canSendRequiredEmail && Umbraco.Sys.ServerVariables.umbracoSettings.allowPasswordReset;
|
||||
vm.errorMsg = "";
|
||||
vm.externalLoginFormAction = Umbraco.Sys.ServerVariables.umbracoUrls.externalLoginsUrl;
|
||||
vm.externalLoginProviders = externalLoginInfo.providers;
|
||||
vm.externalLoginProviders = externalLoginInfoService.getLoginProviders();
|
||||
vm.externalLoginProviders.forEach(x => {
|
||||
x.customView = externalLoginInfoService.getLoginProviderView(x);
|
||||
// if there are errors set for this specific provider than assign them directly to the model
|
||||
if (externalLoginInfo.errorProvider === x.authType) {
|
||||
x.errors = externalLoginInfo.errors;
|
||||
}
|
||||
});
|
||||
vm.denyLocalLogin = externalLoginInfoService.hasDenyLocalLogin();
|
||||
vm.externalLoginInfo = externalLoginInfo;
|
||||
vm.resetPasswordCodeInfo = resetPasswordCodeInfo;
|
||||
vm.backgroundImage = Umbraco.Sys.ServerVariables.umbracoSettings.loginBackgroundImage;
|
||||
@@ -62,7 +73,7 @@
|
||||
vm.setPasswordSubmit = setPasswordSubmit;
|
||||
vm.labels = {};
|
||||
localizationService.localizeMany([
|
||||
vm.usernameIsEmail ? "general_email" : "general_username",
|
||||
vm.usernameIsEmail ? "general_email" : "general_username",
|
||||
vm.usernameIsEmail ? "placeholders_email" : "placeholders_usernameHint",
|
||||
vm.usernameIsEmail ? "placeholders_emptyEmail" : "placeholders_emptyUsername",
|
||||
"placeholders_emptyPassword"]
|
||||
@@ -72,9 +83,11 @@
|
||||
vm.labels.usernameError = data[2];
|
||||
vm.labels.passwordError = data[3];
|
||||
});
|
||||
|
||||
|
||||
vm.twoFactor = {};
|
||||
|
||||
vm.loginSuccess = loginSuccess;
|
||||
|
||||
function onInit() {
|
||||
|
||||
// Check if it is a new user
|
||||
@@ -98,11 +111,11 @@
|
||||
|
||||
//localize the text
|
||||
localizationService.localize("errorHandling_errorInPasswordFormat", [
|
||||
vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength,
|
||||
vm.invitedUserPasswordModel.passwordPolicies.minNonAlphaNumericChars
|
||||
]).then(function (data) {
|
||||
vm.invitedUserPasswordModel.passwordPolicyText = data;
|
||||
});
|
||||
vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength,
|
||||
vm.invitedUserPasswordModel.passwordPolicies.minNonAlphaNumericChars
|
||||
]).then(function (data) {
|
||||
vm.invitedUserPasswordModel.passwordPolicyText = data;
|
||||
});
|
||||
})
|
||||
]).then(function () {
|
||||
vm.inviteStep = Number(inviteVal);
|
||||
@@ -144,12 +157,12 @@
|
||||
|
||||
function getStarted() {
|
||||
$location.search('invite', null);
|
||||
if(vm.onLogin) {
|
||||
if (vm.onLogin) {
|
||||
vm.onLogin();
|
||||
}
|
||||
}
|
||||
|
||||
function inviteSavePassword () {
|
||||
function inviteSavePassword() {
|
||||
|
||||
if (formHelper.submitForm({ scope: $scope })) {
|
||||
|
||||
@@ -197,37 +210,41 @@
|
||||
SetTitle();
|
||||
}
|
||||
|
||||
function loginSuccess() {
|
||||
vm.loginStates.submitButton = "success";
|
||||
userService._retryRequestQueue(true);
|
||||
if (vm.onLogin) {
|
||||
vm.onLogin();
|
||||
}
|
||||
}
|
||||
|
||||
function loginSubmit() {
|
||||
|
||||
if (formHelper.submitForm({ scope: $scope })) {
|
||||
|
||||
if (formHelper.submitForm({ scope: $scope, formCtrl: vm.loginForm })) {
|
||||
//if the login and password are not empty we need to automatically
|
||||
// validate them - this is because if there are validation errors on the server
|
||||
// then the user has to change both username & password to resubmit which isn't ideal,
|
||||
// so if they're not empty, we'll just make sure to set them to valid.
|
||||
if (vm.login && vm.password && vm.login.length > 0 && vm.password.length > 0) {
|
||||
if (vm.login && vm.password && vm.login.length > 0 && vm.password.length > 0) {
|
||||
vm.loginForm.username.$setValidity('auth', true);
|
||||
vm.loginForm.password.$setValidity('auth', true);
|
||||
}
|
||||
|
||||
|
||||
if (vm.loginForm.$invalid) {
|
||||
SetTitle();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// make sure that we are returning to the login view.
|
||||
vm.view = "login";
|
||||
|
||||
vm.loginStates.submitButton = "busy";
|
||||
|
||||
userService.authenticate(vm.login, vm.password)
|
||||
.then(function(data) {
|
||||
vm.loginStates.submitButton = "success";
|
||||
userService._retryRequestQueue(true);
|
||||
if (vm.onLogin) {
|
||||
vm.onLogin();
|
||||
}
|
||||
},
|
||||
function(reason) {
|
||||
.then(function (data) {
|
||||
loginSuccess();
|
||||
},
|
||||
function (reason) {
|
||||
|
||||
//is Two Factor required?
|
||||
if (reason.status === 402) {
|
||||
@@ -249,13 +266,13 @@
|
||||
//setup a watch for both of the model values changing, if they change
|
||||
// while the form is invalid, then revalidate them so that the form can
|
||||
// be submitted again.
|
||||
vm.loginForm.username.$viewChangeListeners.push(function() {
|
||||
vm.loginForm.username.$viewChangeListeners.push(function () {
|
||||
if (vm.loginForm.$invalid) {
|
||||
vm.loginForm.username.$setValidity('auth', true);
|
||||
vm.loginForm.password.$setValidity('auth', true);
|
||||
}
|
||||
});
|
||||
vm.loginForm.password.$viewChangeListeners.push(function() {
|
||||
vm.loginForm.password.$viewChangeListeners.push(function () {
|
||||
if (vm.loginForm.$invalid) {
|
||||
vm.loginForm.username.$setValidity('auth', true);
|
||||
vm.loginForm.password.$setValidity('auth', true);
|
||||
@@ -460,7 +477,7 @@
|
||||
case "2fa-login":
|
||||
title = "Two Factor Authentication";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$emit("$changeTitle", title);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ Use this directive to render an umbraco button. The directive can be used to gen
|
||||
bindings: {
|
||||
action: "&?",
|
||||
href: "@?",
|
||||
hrefTarget: "@?",
|
||||
type: "@",
|
||||
buttonStyle: "@?",
|
||||
state: "<?",
|
||||
@@ -123,6 +124,10 @@ Use this directive to render an umbraco button. The directive can be used to gen
|
||||
vm.innerState = "init";
|
||||
vm.generalActions = vm.labelKey === "general_actions";
|
||||
|
||||
if (!vm.type) {
|
||||
vm.type = "button"; // set the default
|
||||
}
|
||||
|
||||
vm.buttonLabel = vm.label;
|
||||
// is this a primary button style (i.e. anything but an 'info' button)?
|
||||
vm.isPrimaryButtonStyle = vm.buttonStyle && vm.buttonStyle !== 'info';
|
||||
@@ -166,7 +171,7 @@ Use this directive to render an umbraco button. The directive can be used to gen
|
||||
vm.innerState = changes.state.currentValue;
|
||||
}
|
||||
if (changes.state.currentValue === 'success' || changes.state.currentValue === 'error') {
|
||||
// set the state back to 'init' after a success or error
|
||||
// set the state back to 'init' after a success or error
|
||||
$timeout(function () {
|
||||
vm.innerState = 'init';
|
||||
}, 2000);
|
||||
@@ -191,6 +196,13 @@ Use this directive to render an umbraco button. The directive can be used to gen
|
||||
setButtonLabel();
|
||||
}
|
||||
|
||||
// watch for type changes
|
||||
if(changes.type) {
|
||||
if (!vm.type) {
|
||||
vm.type = "button";// set the default
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function clickButton(event) {
|
||||
|
||||
@@ -6,6 +6,7 @@ angular.module('umbraco.interceptors', [])
|
||||
|
||||
$httpProvider.interceptors.push('securityInterceptor');
|
||||
$httpProvider.interceptors.push('debugRequestInterceptor');
|
||||
$httpProvider.interceptors.push('requiredHeadersInterceptor');
|
||||
$httpProvider.interceptors.push('doNotPostDollarVariablesOnPostRequestInterceptor');
|
||||
$httpProvider.interceptors.push('cultureRequestInterceptor');
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Used to set required headers on all requests where necessary
|
||||
* @param {any} $q
|
||||
* @param {any} urlHelper
|
||||
*/
|
||||
function requiredHeadersInterceptor($q, urlHelper) {
|
||||
return {
|
||||
//dealing with requests:
|
||||
'request': function (config) {
|
||||
|
||||
// This is a standard header that should be sent for all ajax requests and is required for
|
||||
// how the server handles auth rejections, etc... see
|
||||
// https://github.com/aspnet/AspNetKatana/blob/e2b18ec84ceab7ffa29d80d89429c9988ab40144/src/Microsoft.Owin.Security.Cookies/Provider/DefaultBehavior.cs
|
||||
// https://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
|
||||
config.headers["X-Requested-With"] = "XMLHttpRequest";
|
||||
|
||||
return config;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.interceptors').factory('requiredHeadersInterceptor', requiredHeadersInterceptor);
|
||||
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.services.externalLoginInfoService
|
||||
* @description A service for working with external login providers
|
||||
**/
|
||||
function externalLoginInfoService(externalLoginInfo, umbRequestHelper) {
|
||||
|
||||
function getLoginProvider(provider) {
|
||||
if (provider) {
|
||||
var found = _.find(externalLoginInfo.providers, x => x.authType == provider);
|
||||
return found;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getLoginProviderView(provider) {
|
||||
if (provider && provider.properties.UmbracoBackOfficeExternalLoginOptions && provider.properties.UmbracoBackOfficeExternalLoginOptions.CustomBackOfficeView) {
|
||||
return umbRequestHelper.convertVirtualToAbsolutePath(provider.properties.UmbracoBackOfficeExternalLoginOptions.CustomBackOfficeView);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any provider denies local login if `provider` is null, else whether the passed
|
||||
* @param {any} provider
|
||||
*/
|
||||
function hasDenyLocalLogin(provider) {
|
||||
if (!provider) {
|
||||
return _.some(externalLoginInfo.providers, x => x.properties.UmbracoBackOfficeExternalLoginOptions.DenyLocalLogin === true);
|
||||
}
|
||||
else {
|
||||
return provider.properties.UmbracoBackOfficeExternalLoginOptions.DenyLocalLogin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all login providers
|
||||
*/
|
||||
function getLoginProviders() {
|
||||
return externalLoginInfo.providers;
|
||||
}
|
||||
|
||||
/** Returns all logins providers that have options that the user can interact with */
|
||||
function getLoginProvidersWithOptions() {
|
||||
// only include providers that allow manual linking or ones that provide a custom view
|
||||
var providers = _.filter(externalLoginInfo.providers, x => {
|
||||
// transform the data and also include the custom view as a nicer property
|
||||
x.customView = getLoginProviderView(x);
|
||||
if (x.customView) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return x.properties.ExternalSignInAutoLinkOptions.AllowManualLinking;
|
||||
}
|
||||
});
|
||||
return providers;
|
||||
}
|
||||
|
||||
return {
|
||||
hasDenyLocalLogin: hasDenyLocalLogin,
|
||||
getLoginProvider: getLoginProvider,
|
||||
getLoginProviders: getLoginProviders,
|
||||
getLoginProvidersWithOptions: getLoginProvidersWithOptions,
|
||||
getLoginProviderView: getLoginProviderView
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.services').factory('externalLoginInfoService', externalLoginInfoService);
|
||||
@@ -5,11 +5,15 @@
|
||||
var elementToInert = document.querySelector('#mainwrapper');
|
||||
|
||||
function addInertAttribute() {
|
||||
elementToInert.setAttribute('inert', true);
|
||||
if (elementToInert) {
|
||||
elementToInert.setAttribute('inert', true);
|
||||
}
|
||||
}
|
||||
|
||||
function removeInertAttribute() {
|
||||
elementToInert.removeAttribute('inert');
|
||||
if (elementToInert) {
|
||||
elementToInert.removeAttribute('inert');
|
||||
}
|
||||
}
|
||||
|
||||
var service = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module('umbraco.services')
|
||||
.factory('userService', function ($rootScope, eventsService, $q, $location, requestRetryQueue, authResource, emailMarketingResource, $timeout, angularHelper) {
|
||||
.factory('userService', function ($rootScope, eventsService, $q, $location, $window, requestRetryQueue, authResource, emailMarketingResource, $timeout, angularHelper) {
|
||||
|
||||
var currentUser = null;
|
||||
var lastUserId = null;
|
||||
@@ -166,7 +166,7 @@ angular.module('umbraco.services')
|
||||
},
|
||||
|
||||
/** Internal method to retry all request after sucessfull login */
|
||||
_retryRequestQueue: function(success) {
|
||||
_retryRequestQueue: function (success) {
|
||||
retryRequestQueue(success)
|
||||
},
|
||||
|
||||
@@ -185,18 +185,22 @@ angular.module('umbraco.services')
|
||||
authenticate: function (login, password) {
|
||||
|
||||
return authResource.performLogin(login, password)
|
||||
.then(function(data) {
|
||||
.then(function (data) {
|
||||
|
||||
// Check if user has a start node set.
|
||||
if(data.startContentIds.length === 0 && data.startMediaIds.length === 0){
|
||||
if (data.startContentIds.length === 0 && data.startMediaIds.length === 0) {
|
||||
var errorMsg = "User has no start-nodes";
|
||||
var result = { errorMsg: errorMsg, user: data, authenticated: false, lastUserId: lastUserId, loginType: "credentials" };
|
||||
eventsService.emit("app.notAuthenticated", result);
|
||||
// TODO: How does this make sense? How can you throw from a promise? Does this get caught by the rejection?
|
||||
// If so then return $q.reject should be used.
|
||||
throw result;
|
||||
}
|
||||
|
||||
|
||||
return data;
|
||||
|
||||
|
||||
}, function (err) {
|
||||
return $q.reject(err);
|
||||
}).then(this.setAuthenticationSuccessful);
|
||||
},
|
||||
setAuthenticationSuccessful: function (data) {
|
||||
@@ -218,8 +222,14 @@ angular.module('umbraco.services')
|
||||
return authResource.performLogout()
|
||||
.then(function (data) {
|
||||
userAuthExpired();
|
||||
//done!
|
||||
return null;
|
||||
|
||||
if (data && data.signOutRedirectUrl) {
|
||||
$window.location.replace(data.signOutRedirectUrl);
|
||||
}
|
||||
else {
|
||||
//done!
|
||||
return null;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -235,9 +245,9 @@ angular.module('umbraco.services')
|
||||
setCurrentUser(data);
|
||||
|
||||
deferred.resolve(currentUser);
|
||||
}, function () {
|
||||
}, function (err) {
|
||||
//it failed, so they are not logged in
|
||||
deferred.reject();
|
||||
deferred.reject(err);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
@@ -245,7 +255,7 @@ angular.module('umbraco.services')
|
||||
|
||||
/** Returns the current user object in a promise */
|
||||
getCurrentUser: function (args) {
|
||||
|
||||
|
||||
if (!currentUser) {
|
||||
return authResource.getCurrentUser()
|
||||
.then(function (data) {
|
||||
@@ -260,9 +270,9 @@ angular.module('umbraco.services')
|
||||
setCurrentUser(data);
|
||||
|
||||
return $q.when(currentUser);
|
||||
}, function () {
|
||||
}, function (err) {
|
||||
//it failed, so they are not logged in
|
||||
return $q.reject(currentUser);
|
||||
return $q.reject(err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.Overlays.UserController", function ($scope, $location, $timeout, dashboardResource, userService, historyService, eventsService, externalLoginInfo, authResource, currentUserResource, formHelper, localizationService) {
|
||||
.controller("Umbraco.Overlays.UserController", function ($scope, $location, $timeout,
|
||||
dashboardResource, userService, historyService, eventsService,
|
||||
externalLoginInfo, externalLoginInfoService, authResource,
|
||||
currentUserResource, formHelper, localizationService) {
|
||||
|
||||
$scope.history = historyService.getCurrent();
|
||||
//$scope.version = Umbraco.Sys.ServerVariables.application.version + " assembly: " + Umbraco.Sys.ServerVariables.application.assemblyVersion;
|
||||
@@ -14,7 +17,12 @@ angular.module("umbraco")
|
||||
});
|
||||
}
|
||||
*/
|
||||
$scope.externalLoginProviders = externalLoginInfo.providers;
|
||||
|
||||
// Set flag if any have deny local login, in which case we must disable all password functionality
|
||||
$scope.denyLocalLogin = externalLoginInfoService.hasDenyLocalLogin();
|
||||
// Only include login providers that have editable options
|
||||
$scope.externalLoginProviders = externalLoginInfoService.getLoginProvidersWithOptions();
|
||||
|
||||
$scope.externalLinkLoginFormAction = Umbraco.Sys.ServerVariables.umbracoUrls.externalLinkLoginsUrl;
|
||||
var evts = [];
|
||||
evts.push(eventsService.on("historyService.add", function (e, args) {
|
||||
@@ -72,10 +80,9 @@ angular.module("umbraco")
|
||||
//updateTimeout();
|
||||
|
||||
authResource.getCurrentUserLinkedLogins().then(function(logins) {
|
||||
|
||||
//reset all to be un-linked
|
||||
for (var provider in $scope.externalLoginProviders) {
|
||||
$scope.externalLoginProviders[provider].linkedProviderKey = undefined;
|
||||
}
|
||||
$scope.externalLoginProviders.forEach(provider => provider.linkedProviderKey = undefined);
|
||||
|
||||
//set the linked logins
|
||||
for (var login in logins) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
ng-if="!denyLocalLogin"
|
||||
alias="changePassword"
|
||||
type="button"
|
||||
action="togglePasswordFields()"
|
||||
@@ -49,27 +50,32 @@
|
||||
|
||||
<div ng-repeat="login in externalLoginProviders">
|
||||
|
||||
<form ng-submit="linkProvider($event)" ng-if="login.linkedProviderKey == undefined" method="POST" action="{{externalLinkLoginFormAction}}" name="oauthloginform" id="oauthloginform-{{login.authType}}">
|
||||
<input type="hidden" name="provider" value="{{login.authType}}" />
|
||||
<button class="btn btn-block btn-social"
|
||||
<div ng-if="login.customView" ng-include="login.customView"></div>
|
||||
|
||||
<div ng-if="!login.customView && login.properties.ExternalSignInAutoLinkOptions.AllowManualLinking">
|
||||
<form ng-submit="linkProvider($event)" ng-if="login.linkedProviderKey == undefined" method="POST" action="{{externalLinkLoginFormAction}}" name="oauthloginform" id="oauthloginform-{{login.authType}}">
|
||||
<input type="hidden" name="provider" value="{{login.authType}}" />
|
||||
<button class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
id="{{login.authType}}">
|
||||
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
<localize key="defaultdialogs_linkYour">Link your</localize> {{login.caption}} <localize key="defaultdialogs_account">account</localize>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<button ng-if="login.linkedProviderKey != undefined"
|
||||
ng-click="unlink($event, login.authType, login.linkedProviderKey)"
|
||||
class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
id="{{login.authType}}">
|
||||
|
||||
id="{{login.authType}}"
|
||||
name="provider"
|
||||
value="{{login.authType}}">
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
<localize key="defaultdialogs_linkYour">Link your</localize> {{login.caption}} <localize key="defaultdialogs_account">account</localize>
|
||||
<localize key="defaultdialogs_unLinkYour">Un-link your</localize> {{login.caption}} <localize key="defaultdialogs_account">account</localize>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<button ng-if="login.linkedProviderKey != undefined"
|
||||
ng-click="unlink($event, login.authType, login.linkedProviderKey)"
|
||||
class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
id="{{login.authType}}"
|
||||
name="provider"
|
||||
value="{{login.authType}}">
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
<localize key="defaultdialogs_unLinkYour">Un-link your</localize> {{login.caption}} <localize key="defaultdialogs_account">account</localize>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -86,7 +92,8 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div ng-if="showPasswordFields">
|
||||
|
||||
<div ng-if="showPasswordFields && !denyLocalLogin">
|
||||
|
||||
<h5>
|
||||
<localize key="general_changePassword">Change password</localize>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<img src="assets/img/application/umbraco_logo_white.svg">
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.invitedUser != null" class="umb-login-container">
|
||||
<div ng-if="!vm.denyLocalLogin" ng-show="vm.invitedUser != null" class="umb-login-container">
|
||||
|
||||
<form name="inviteUserPasswordForm" novalidate="" ng-submit="vm.inviteSavePassword()" val-form-manager>
|
||||
<div class="form" ng-if="vm.inviteStep === 1">
|
||||
@@ -100,7 +100,7 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div ng-show="vm.invitedUser == null && vm.inviteStep === 3" ng-if="vm.inviteStep === 3" class="umb-login-container">
|
||||
<div ng-show="vm.invitedUser == null && vm.inviteStep === 3" ng-if="!vm.denyLocalLogin && vm.inviteStep === 3" class="umb-login-container">
|
||||
<div class="form">
|
||||
<h1 style="margin-bottom: 10px; text-align: left;">Hi there</h1>
|
||||
<p style="line-height: 1.6; margin-bottom: 25px;">
|
||||
@@ -120,29 +120,31 @@
|
||||
</p>
|
||||
|
||||
<div class="external-logins" ng-if="vm.externalLoginProviders.length > 0">
|
||||
<div ng-repeat="login in vm.externalLoginProviders">
|
||||
|
||||
<div class="text-error" ng-repeat="error in vm.externalLoginInfo.errors">
|
||||
<span>{{error}}</span>
|
||||
</div>
|
||||
|
||||
<form method="POST" name="vm.externalLoginForm" action="{{vm.externalLoginFormAction}}">
|
||||
|
||||
<div ng-repeat="login in vm.externalLoginProviders">
|
||||
|
||||
<button type="submit" class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
id="{{login.authType}}" name="provider" value="{{login.authType}}"
|
||||
title="Log in using your {{login.caption}} account">
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
<localize key="login_signInWith">Sign in with</localize> {{login.caption}}
|
||||
</button>
|
||||
|
||||
<div ng-if="!login.customView">
|
||||
<form method="POST" action="{{vm.externalLoginFormAction}}">
|
||||
<button type="submit"
|
||||
class="btn btn-block btn-social"
|
||||
ng-class="login.properties.SocialStyle"
|
||||
id="{{login.authType}}" name="provider" value="{{login.authType}}"
|
||||
title="Log in using your {{login.caption}} account">
|
||||
<i class="fa" ng-class="login.properties.SocialIcon"></i>
|
||||
<localize key="login_signInWith">Sign in with</localize> {{login.caption}}
|
||||
</button>
|
||||
</form>
|
||||
<div ng-if="login.errors">
|
||||
<div class="text-error" ng-repeat="error in login.errors">
|
||||
<span>{{error}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div ng-if="login.customView" ng-include="login.customView"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" name="vm.loginForm" ng-submit="vm.loginSubmit()">
|
||||
<form ng-if="!vm.denyLocalLogin" method="POST" name="vm.loginForm" ng-submit="vm.loginSubmit()">
|
||||
|
||||
<div ng-messages="vm.loginForm.$error" class="control-group" aria-live="assertive">
|
||||
<p ng-message="auth" class="text-error" role="alert" tabindex="0">{{vm.errorMsg}}</p>
|
||||
@@ -178,7 +180,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.view == 'request-password-reset'">
|
||||
<div ng-if="!vm.denyLocalLogin" ng-show="vm.view == 'request-password-reset'">
|
||||
<p tabindex="0">
|
||||
<localize key="login_forgottenPasswordInstruction">An email will be sent to the address specified with a link to reset your password</localize>
|
||||
</p>
|
||||
@@ -209,7 +211,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.view == 'set-password'">
|
||||
<div ng-if="!vm.denyLocalLogin" ng-show="vm.view == 'set-password'">
|
||||
|
||||
<p ng-hide="vm.resetComplete">
|
||||
<localize key="login_setPasswordInstruction">Please provide a new password.</localize>
|
||||
@@ -245,7 +247,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.view == 'password-reset-code-expired'">
|
||||
<div ng-if="!vm.denyLocalLogin" ng-show="vm.view == 'password-reset-code-expired'">
|
||||
<div class="text-error" ng-repeat="error in vm.resetPasswordCodeInfo.errors">
|
||||
<p class="text-error">{{error}}</p>
|
||||
</div>
|
||||
@@ -255,7 +257,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.view == '2fa-login'">
|
||||
<div ng-if="!vm.denyLocalLogin" ng-show="vm.view == '2fa-login'">
|
||||
<div ng-include='vm.twoFactor.view'></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<div class="btn-group umb-button-group" ng-class="{ 'dropup': direction === 'up', '-with-button-group-toggle': subButtons.length > 0 }">
|
||||
|
||||
<umb-button
|
||||
type="button"
|
||||
ng-if="defaultButton"
|
||||
alias="{{defaultButton.alias ? defaultButton.alias : 'groupPrimary' }}"
|
||||
type="{{defaultButton.type}}"
|
||||
action="defaultButton.handler()"
|
||||
href="{{defaultButton.href}}"
|
||||
href-target="{{defaultButton.hrefTarget}}"
|
||||
button-style="{{buttonStyle}}"
|
||||
state="state"
|
||||
label="{{defaultButton.labelKey}}"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<a ng-if="vm.type === 'link'"
|
||||
ng-href="{{vm.href}}"
|
||||
ng-attr-target="{{(vm.hrefTarget) ? vm.hrefTarget : undefined}}"
|
||||
class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}} umb-outline"
|
||||
ng-click="vm.clickButton($event)"
|
||||
hotkey="{{vm.shortcut}}"
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function UserEditController($scope, eventsService, $q, $location, $routeParams, formHelper, usersResource, userService, contentEditingHelper, localizationService, mediaHelper, Upload, umbRequestHelper, usersHelper, authResource, dateHelper, editorService, overlayService) {
|
||||
function UserEditController($scope, eventsService, $q, $location, $routeParams, formHelper, usersResource,
|
||||
userService, contentEditingHelper, localizationService, mediaHelper, Upload, umbRequestHelper,
|
||||
usersHelper, authResource, dateHelper, editorService, overlayService, externalLoginInfoService) {
|
||||
|
||||
var currentLoggedInUser = null;
|
||||
|
||||
@@ -46,6 +48,8 @@
|
||||
vm.changePassword = changePassword;
|
||||
vm.toggleChangePassword = toggleChangePassword;
|
||||
|
||||
vm.denyLocalLogin = externalLoginInfoService.hasDenyLocalLogin();
|
||||
|
||||
function init() {
|
||||
|
||||
vm.loading = true;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<umb-editor-view>
|
||||
|
||||
<umb-editor-header name="vm.user.name"
|
||||
name-locked="vm.denyLocalLogin"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function DetailsController($scope, externalLoginInfoService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.denyLocalLogin = externalLoginInfoService.hasDenyLocalLogin();
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Users.DetailsController", DetailsController);
|
||||
|
||||
})();
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="umb-user-details-details">
|
||||
<div ng-controller="Umbraco.Editors.Users.DetailsController as vm" class="umb-user-details-details">
|
||||
|
||||
<div class="umb-user-details-details__main-content">
|
||||
|
||||
@@ -10,22 +10,31 @@
|
||||
|
||||
<umb-control-group label="@general_email" required="true" alias="email">
|
||||
|
||||
<input type="email"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enteremail"
|
||||
class="input-block-level"
|
||||
ng-model="model.user.email"
|
||||
umb-auto-focus
|
||||
name="email"
|
||||
id="email"
|
||||
val-email
|
||||
ng-required="true"
|
||||
val-server-field="Email" />
|
||||
<span ng-messages="userProfileForm.email.$error" show-validation-on-submit>
|
||||
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" ng-message="valEmail"><localize key="validation_invalidEmail">Invalid email</localize></span>
|
||||
<span class="help-inline" ng-message="valServerField">{{userProfileForm.email.errorMsg}}</span>
|
||||
</span>
|
||||
<div ng-if="!vm.denyLocalLogin">
|
||||
<input type="email"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enteremail"
|
||||
class="input-block-level"
|
||||
ng-model="model.user.email"
|
||||
umb-auto-focus
|
||||
name="email"
|
||||
id="email"
|
||||
val-email
|
||||
ng-required="true"
|
||||
val-server-field="Email" />
|
||||
<span ng-messages="userProfileForm.email.$error" show-validation-on-submit>
|
||||
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" ng-message="valEmail"><localize key="validation_invalidEmail">Invalid email</localize></span>
|
||||
<span class="help-inline" ng-message="valServerField">{{userProfileForm.email.errorMsg}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div ng-if="vm.denyLocalLogin">
|
||||
<input type="email"
|
||||
class="input-block-level"
|
||||
ng-model="model.user.email"
|
||||
id="email"
|
||||
disabled />
|
||||
</div>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_username" ng-if="!model.usernameIsEmail" required="true">
|
||||
@@ -254,7 +263,7 @@
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
<div>
|
||||
<div ng-if="!vm.denyLocalLogin">
|
||||
|
||||
<umb-button type="button" ng-if="model.user.userDisplayState.key !== 'Invited'"
|
||||
button-style="[action,block]"
|
||||
@@ -276,7 +285,7 @@
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<div ng-if="model.user.resetPasswordValue">
|
||||
<div ng-if="!vm.denyLocalLogin && model.user.resetPasswordValue">
|
||||
<p><br />Password reset to value: <strong>{{model.user.resetPasswordValue}}</strong></p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
function UsersController($scope, $timeout, $location, $routeParams, usersResource,
|
||||
userGroupsResource, userService, localizationService,
|
||||
usersHelper, formHelper, dateHelper, editorService,
|
||||
listViewHelper) {
|
||||
listViewHelper, externalLoginInfoService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
@@ -69,32 +69,43 @@
|
||||
// Get last selected layout for "users" (defaults to first layout = card layout)
|
||||
vm.activeLayout = listViewHelper.getLayout("users", vm.layouts);
|
||||
|
||||
vm.denyLocalLogin = externalLoginInfoService.hasDenyLocalLogin();
|
||||
|
||||
// returns the object representing the user create button, returns null if deny local login is true
|
||||
function getCreateUserButton() {
|
||||
if (!vm.denyLocalLogin) {
|
||||
return {
|
||||
type: "button",
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// No default buttons with denyLocalLogin
|
||||
// Don't show the invite button if no email is configured
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.showUserInvite) {
|
||||
vm.defaultButton = {
|
||||
type: "button",
|
||||
labelKey: "user_inviteUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('inviteUser');
|
||||
}
|
||||
};
|
||||
vm.subButtons = [
|
||||
{
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
}
|
||||
];
|
||||
var createUserBtn = getCreateUserButton();
|
||||
if (createUserBtn) {
|
||||
vm.subButtons = [createUserBtn];
|
||||
}
|
||||
}
|
||||
else {
|
||||
vm.defaultButton = {
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
};
|
||||
vm.defaultButton = getCreateUserButton();
|
||||
}
|
||||
|
||||
|
||||
|
||||
vm.toggleFilter = toggleFilter;
|
||||
vm.setUsersViewState = setUsersViewState;
|
||||
vm.selectLayout = selectLayout;
|
||||
|
||||
@@ -502,7 +502,7 @@
|
||||
</umb-checkmark>
|
||||
<h3 class="bold" style="margin: 0 0 0 10px;">
|
||||
{{vm.newUser.name | umbWordLimit:1}}
|
||||
<localize key="user_userInvited">has been created</localize>
|
||||
<localize key="user_userInvited">has been invited</localize>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@@ -517,6 +517,7 @@
|
||||
size="m">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
ng-if="vm.newUser.id"
|
||||
type="button"
|
||||
button-style="action"
|
||||
label-key="user_goToProfile"
|
||||
|
||||
Reference in New Issue
Block a user