Browse Source

change admin password after first login

Patrick O'Carroll 7 years ago
parent
commit
cb6c6c8172

+ 59 - 7
public/app/core/controllers/login_ctrl.ts

@@ -11,10 +11,15 @@ export class LoginCtrl {
       password: '',
     };
 
+    $scope.command = {};
+    $scope.result = '';
+
     contextSrv.sidemenu = false;
 
     $scope.oauth = config.oauth;
     $scope.oauthEnabled = _.keys(config.oauth).length > 0;
+    $scope.ldapEnabled = config.ldapEnabled;
+    $scope.authProxyEnabled = config.authProxyEnabled;
 
     $scope.disableLoginForm = config.disableLoginForm;
     $scope.disableUserSignUp = config.disableUserSignUp;
@@ -39,6 +44,43 @@ export class LoginCtrl {
       }
     };
 
+    $scope.changeView = function() {
+      let loginView = document.querySelector('#login-view');
+      let changePasswordView = document.querySelector('#change-password-view');
+
+      loginView.className += ' add';
+      setTimeout(() => {
+        loginView.className += ' hidden';
+      }, 250);
+      setTimeout(() => {
+        changePasswordView.classList.remove('hidden');
+      }, 251);
+      setTimeout(() => {
+        changePasswordView.classList.remove('remove');
+      }, 301);
+
+      setTimeout(() => {
+        document.getElementById('newPassword').focus();
+      }, 400);
+    };
+
+    $scope.changePassword = function() {
+      $scope.command.oldPassword = 'admin';
+
+      if ($scope.command.newPassword !== $scope.command.confirmNew) {
+        $scope.appEvent('alert-warning', ['New passwords do not match', '']);
+        return;
+      }
+
+      backendSrv.put('/api/user/password', $scope.command).then(function() {
+        $scope.toGrafana();
+      });
+    };
+
+    $scope.skip = function() {
+      $scope.toGrafana();
+    };
+
     $scope.loginModeChanged = function(newValue) {
       $scope.submitBtnText = newValue ? 'Log in' : 'Sign up';
     };
@@ -65,18 +107,28 @@ export class LoginCtrl {
       }
 
       backendSrv.post('/login', $scope.formModel).then(function(result) {
-        var params = $location.search();
+        $scope.result = result;
 
-        if (params.redirect && params.redirect[0] === '/') {
-          window.location.href = config.appSubUrl + params.redirect;
-        } else if (result.redirectUrl) {
-          window.location.href = result.redirectUrl;
-        } else {
-          window.location.href = config.appSubUrl + '/';
+        if ($scope.formModel.password !== 'admin' || $scope.ldapEnabled || $scope.authProxyEnabled) {
+          $scope.toGrafana();
+          return;
         }
+        $scope.changeView();
       });
     };
 
+    $scope.toGrafana = function() {
+      var params = $location.search();
+
+      if (params.redirect && params.redirect[0] === '/') {
+        window.location.href = config.appSubUrl + params.redirect;
+      } else if ($scope.result.redirectUrl) {
+        window.location.href = $scope.result.redirectUrl;
+      } else {
+        window.location.href = config.appSubUrl + '/';
+      }
+    };
+
     $scope.init();
   }
 }

+ 82 - 51
public/app/partials/login.html

@@ -4,70 +4,101 @@
       <img class="logo-icon" src="public/img/grafana_icon.svg" alt="Grafana" />
       <i class="icon-gf icon-gf-grafana_wordmark"></i>
     </div>
-    <div class="login-inner-box">
-      <form name="loginForm" class="login-form-group gf-form-group" ng-hide="disableLoginForm">
-        <div class="login-form">
-          <input type="text" name="username" class="gf-form-input login-form-input" required ng-model='formModel.user' placeholder={{loginHint}}
-            autofocus>
-        </div>
-        <div class="login-form">
-          <input type="password" name="password" class="gf-form-input login-form-input" required ng-model="formModel.password" id="inputPassword"
-            placeholder="password">
-        </div>
-        <div class="login-button-group">
-          <button type="submit" class="btn btn-large p-x-2" ng-click="submit();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
-            Log In
-          </button>
+    <div class="login-outer-box">
+      <div class="login-inner-box" id="login-view">
+        <form name="loginForm" class="login-form-group gf-form-group" ng-hide="disableLoginForm">
+          <div class="login-form">
+            <input type="text" name="username" class="gf-form-input login-form-input" required ng-model='formModel.user' placeholder={{loginHint}}
+              autofocus>
+          </div>
+          <div class="login-form">
+            <input type="password" name="password" class="gf-form-input login-form-input" required ng-model="formModel.password" id="inputPassword"
+              placeholder="password">
+          </div>
+          <div class="login-button-group">
+            <button type="submit" class="btn btn-large p-x-2" ng-click="submit();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
+              Log In
+            </button>
             <div class="small login-button-forgot-password">
               <a href="user/password/send-reset-email">
                 Forgot your password?
               </a>
+            </div>
           </div>
-        </div>
-      </form>
-      <div class="text-center login-divider" ng-show="oauthEnabled">
-        <div>
-          <div class="login-divider-line">
+        </form>
+        <div class="text-center login-divider" ng-show="oauthEnabled">
+          <div>
+            <div class="login-divider-line">
+            </div>
+          </div>
+          <div>
+            <span class="login-divider-text">
+              <span ng-hide="disableLoginForm">or</span>
+            </span>
+          </div>
+          <div>
+            <div class="login-divider-line">
+            </div>
           </div>
         </div>
-        <div>
-          <span class="login-divider-text">
-            <span ng-hide="disableLoginForm">or</span>
-          </span>
+        <div class="clearfix"></div>
+        <div class="login-oauth text-center" ng-show="oauthEnabled">
+          <a class="btn btn-medium btn-service btn-service--google login-btn" href="login/google" target="_self" ng-if="oauth.google">
+            <i class="btn-service-icon fa fa-google"></i>
+            Sign in with Google
+          </a>
+          <a class="btn btn-medium btn-service btn-service--github login-btn" href="login/github" target="_self" ng-if="oauth.github">
+            <i class="btn-service-icon fa fa-github"></i>
+            Sign in with GitHub
+          </a>
+          <a class="btn btn-medium btn-inverse btn-service btn-service--grafanacom login-btn" href="login/grafana_com" target="_self"
+            ng-if="oauth.grafana_com">
+            <i class="btn-service-icon"></i>
+            Sign in with Grafana.com
+          </a>
+          <a class="btn btn-medium btn-inverse btn-service btn-service--oauth login-btn" href="login/generic_oauth" target="_self"
+            ng-if="oauth.generic_oauth">
+            <i class="btn-service-icon fa fa-sign-in"></i>
+            Sign in with {{oauth.generic_oauth.name}}
+          </a>
         </div>
-        <div>
-          <div class="login-divider-line">
+        <div class="login-signup-box" ng-show="!disableUserSignUp">
+          <div class="login-signup-title p-r-1">
+            New to Grafana?
           </div>
+          <a href="signup" class="btn btn-medium btn-signup btn-p-x-2">
+            Sign Up
+          </a>
         </div>
       </div>
-      <div class="clearfix"></div>
-      <div class="login-oauth text-center" ng-show="oauthEnabled">
-        <a class="btn btn-medium btn-service btn-service--google login-btn" href="login/google" target="_self" ng-if="oauth.google">
-          <i class="btn-service-icon fa fa-google"></i>
-          Sign in with Google
-        </a>
-        <a class="btn btn-medium btn-service btn-service--github login-btn" href="login/github" target="_self" ng-if="oauth.github">
-          <i class="btn-service-icon fa fa-github"></i>
-          Sign in with GitHub
-        </a>
-        <a class="btn btn-medium btn-inverse btn-service btn-service--grafanacom login-btn" href="login/grafana_com" target="_self" ng-if="oauth.grafana_com">
-          <i class="btn-service-icon"></i>
-          Sign in with Grafana.com
-        </a>
-        <a class="btn btn-medium btn-inverse btn-service btn-service--oauth login-btn" href="login/generic_oauth" target="_self" ng-if="oauth.generic_oauth">
-          <i class="btn-service-icon fa fa-sign-in"></i>
-          Sign in with {{oauth.generic_oauth.name}}
-        </a>
-      </div>
-      <div class="login-signup-box" ng-show="!disableUserSignUp">
-        <div class="login-signup-title p-r-1">
-          New to Grafana?
+      <div class="login-inner-box remove hidden" id="change-password-view">
+        <div class="text-left login-change-password-info">
+          <h5>Change Password</h5>
+          Before you can get started with awesome dashboards we need you to make your account more secure by changing your password.
+          <br />You can change your password again later.
         </div>
-        <a href="signup" class="btn btn-medium btn-signup btn-p-x-2">
-          Sign Up
-        </a>
+        <form class="login-form-group gf-form-group">
+          <div class="login-form">
+            <input type="password" id="newPassword" name="newPassword" class="gf-form-input login-form-input" required ng-model='command.newPassword'
+              placeholder="New password">
+          </div>
+          <div class="login-form">
+            <input type="password" name="confirmNew" class="gf-form-input login-form-input" required ng-model="command.confirmNew" placeholder="Confirm new password">
+          </div>
+          <div class="login-button-group login-button-group--right text-right">
+            <a class="btn btn-link" ng-click="skip();">
+              Skip
+              <info-popover mode="no-padding">
+                If you skip you will be promted to change password next time you login.
+              </info-popover>
+            </a>
+            <button type="submit" class="btn btn-large p-x-2" ng-click="changePassword();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-success': loginForm.$valid}">
+              Save
+            </button>
+          </div>
+        </form>
       </div>
+      <div class="clearfix"></div>
     </div>
-    <div class="clearfix"></div>
   </div>
 </div>

+ 4 - 0
public/sass/components/_gf-form.scss

@@ -384,6 +384,10 @@ $input-border: 1px solid $input-border-color;
   &--header {
     margin-bottom: $gf-form-margin;
   }
+
+  &--no-padding {
+    padding-left: 0;
+  }
 }
 
 select.gf-form-input ~ .gf-form-help-icon {

+ 38 - 0
public/sass/pages/_login.scss

@@ -59,6 +59,14 @@ select:-webkit-autofill:focus {
   justify-content: space-between;
   width: 100%;
   margin-top: 0.5rem;
+
+  &--right {
+    justify-content: flex-end;
+
+    & .btn {
+      margin-left: 1rem;
+    }
+  }
 }
 
 .login-button-forgot-password {
@@ -75,7 +83,9 @@ select:-webkit-autofill:focus {
   align-items: stretch;
   flex-direction: column;
   position: relative;
+  justify-content: center;
   z-index: 1;
+  height: 320px;
 }
 
 .login-branding {
@@ -100,6 +110,11 @@ select:-webkit-autofill:focus {
   }
 }
 
+.login-outer-box {
+  display: flex;
+  overflow-y: hidden;
+}
+
 .login-inner-box {
   text-align: center;
   padding: 2rem 4rem;
@@ -109,6 +124,22 @@ select:-webkit-autofill:focus {
   justify-content: center;
   flex-grow: 1;
   max-width: 415px;
+  transform: tranlate(0px, 0px);
+  transition: 0.25s ease;
+
+  &.add {
+    transform: translate(0px, -320px);
+    &.hidden {
+      display: none;
+    }
+  }
+
+  &.remove {
+    transform: translate(0px, 320px);
+    &.hidden {
+      display: none;
+    }
+  }
 }
 
 .login-tab-header {
@@ -117,6 +148,13 @@ select:-webkit-autofill:focus {
   margin-bottom: 3rem;
 }
 
+.login-change-password-info {
+  padding-bottom: 1.5rem;
+
+  & h5 {
+    text-align: left;
+  }
+}
 .btn-signup {
   color: $white;
   border: 1px solid $login-border;