mirror of https://github.com/jumpserver/jumpserver
reset user password and ssh pk implement
parent
00502ce33d
commit
6751c5a63a
|
@ -0,0 +1,715 @@
|
|||
body.stop-scrolling {
|
||||
height: 100%;
|
||||
overflow: hidden; }
|
||||
|
||||
.sweet-overlay {
|
||||
background-color: black;
|
||||
/* IE8 */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
|
||||
/* IE8 */
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
z-index: 10000; }
|
||||
|
||||
.sweet-alert {
|
||||
background-color: white;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
width: 478px;
|
||||
padding: 17px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -256px;
|
||||
margin-top: -200px;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
z-index: 99999; }
|
||||
@media all and (max-width: 540px) {
|
||||
.sweet-alert {
|
||||
width: auto;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
left: 15px;
|
||||
right: 15px; } }
|
||||
.sweet-alert h2 {
|
||||
color: #575757;
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
position: relative;
|
||||
margin: 25px 0;
|
||||
padding: 0;
|
||||
line-height: 40px;
|
||||
display: block; }
|
||||
.sweet-alert p {
|
||||
color: #797979;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
position: relative;
|
||||
text-align: inherit;
|
||||
float: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: normal; }
|
||||
.sweet-alert fieldset {
|
||||
border: none;
|
||||
position: relative; }
|
||||
.sweet-alert .sa-error-container {
|
||||
background-color: #f1f1f1;
|
||||
margin-left: -17px;
|
||||
margin-right: -17px;
|
||||
overflow: hidden;
|
||||
padding: 0 10px;
|
||||
max-height: 0;
|
||||
webkit-transition: padding 0.15s, max-height 0.15s;
|
||||
transition: padding 0.15s, max-height 0.15s; }
|
||||
.sweet-alert .sa-error-container.show {
|
||||
padding: 10px 0;
|
||||
max-height: 100px;
|
||||
webkit-transition: padding 0.2s, max-height 0.2s;
|
||||
transition: padding 0.25s, max-height 0.25s; }
|
||||
.sweet-alert .sa-error-container .icon {
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background-color: #ea7d7d;
|
||||
color: white;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
margin-right: 3px; }
|
||||
.sweet-alert .sa-error-container p {
|
||||
display: inline-block; }
|
||||
.sweet-alert .sa-input-error {
|
||||
position: absolute;
|
||||
top: 29px;
|
||||
right: 26px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.5);
|
||||
transform: scale(0.5);
|
||||
-webkit-transform-origin: 50% 50%;
|
||||
transform-origin: 50% 50%;
|
||||
-webkit-transition: all 0.1s;
|
||||
transition: all 0.1s; }
|
||||
.sweet-alert .sa-input-error::before, .sweet-alert .sa-input-error::after {
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 6px;
|
||||
background-color: #f06e57;
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -4px;
|
||||
left: 50%;
|
||||
margin-left: -9px; }
|
||||
.sweet-alert .sa-input-error::before {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg); }
|
||||
.sweet-alert .sa-input-error::after {
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg); }
|
||||
.sweet-alert .sa-input-error.show {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
.sweet-alert input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #d7d7d7;
|
||||
height: 43px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 17px;
|
||||
font-size: 18px;
|
||||
box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.06);
|
||||
padding: 0 12px;
|
||||
display: none;
|
||||
-webkit-transition: all 0.3s;
|
||||
transition: all 0.3s; }
|
||||
.sweet-alert input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0px 0px 3px #c4e6f5;
|
||||
border: 1px solid #b4dbed; }
|
||||
.sweet-alert input:focus::-moz-placeholder {
|
||||
transition: opacity 0.3s 0.03s ease;
|
||||
opacity: 0.5; }
|
||||
.sweet-alert input:focus:-ms-input-placeholder {
|
||||
transition: opacity 0.3s 0.03s ease;
|
||||
opacity: 0.5; }
|
||||
.sweet-alert input:focus::-webkit-input-placeholder {
|
||||
transition: opacity 0.3s 0.03s ease;
|
||||
opacity: 0.5; }
|
||||
.sweet-alert input::-moz-placeholder {
|
||||
color: #bdbdbd; }
|
||||
.sweet-alert input:-ms-input-placeholder {
|
||||
color: #bdbdbd; }
|
||||
.sweet-alert input::-webkit-input-placeholder {
|
||||
color: #bdbdbd; }
|
||||
.sweet-alert.show-input input {
|
||||
display: block; }
|
||||
.sweet-alert button {
|
||||
background-color: #AEDEF4;
|
||||
color: white;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 5px;
|
||||
padding: 10px 32px;
|
||||
margin: 26px 5px 0 5px;
|
||||
cursor: pointer; }
|
||||
.sweet-alert button:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); }
|
||||
.sweet-alert button:hover {
|
||||
background-color: #a1d9f2; }
|
||||
.sweet-alert button:active {
|
||||
background-color: #81ccee; }
|
||||
.sweet-alert button.cancel {
|
||||
background-color: #D0D0D0; }
|
||||
.sweet-alert button.cancel:hover {
|
||||
background-color: #c8c8c8; }
|
||||
.sweet-alert button.cancel:active {
|
||||
background-color: #b6b6b6; }
|
||||
.sweet-alert button.cancel:focus {
|
||||
box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; }
|
||||
.sweet-alert button::-moz-focus-inner {
|
||||
border: 0; }
|
||||
.sweet-alert[data-has-cancel-button=false] button {
|
||||
box-shadow: none !important; }
|
||||
.sweet-alert[data-has-confirm-button=false][data-has-cancel-button=false] {
|
||||
padding-bottom: 40px; }
|
||||
.sweet-alert .sa-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 4px solid gray;
|
||||
-webkit-border-radius: 40px;
|
||||
border-radius: 40px;
|
||||
border-radius: 50%;
|
||||
margin: 20px auto;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
box-sizing: content-box; }
|
||||
.sweet-alert .sa-icon.sa-error {
|
||||
border-color: #F27474; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-x-mark {
|
||||
position: relative;
|
||||
display: block; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-line {
|
||||
position: absolute;
|
||||
height: 5px;
|
||||
width: 47px;
|
||||
background-color: #F27474;
|
||||
display: block;
|
||||
top: 37px;
|
||||
border-radius: 2px; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-left {
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
left: 17px; }
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-right {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
right: 16px; }
|
||||
.sweet-alert .sa-icon.sa-warning {
|
||||
border-color: #F8BB86; }
|
||||
.sweet-alert .sa-icon.sa-warning .sa-body {
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 47px;
|
||||
left: 50%;
|
||||
top: 10px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
margin-left: -2px;
|
||||
background-color: #F8BB86; }
|
||||
.sweet-alert .sa-icon.sa-warning .sa-dot {
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
margin-left: -3px;
|
||||
left: 50%;
|
||||
bottom: 10px;
|
||||
background-color: #F8BB86; }
|
||||
.sweet-alert .sa-icon.sa-info {
|
||||
border-color: #C9DAE1; }
|
||||
.sweet-alert .sa-icon.sa-info::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 29px;
|
||||
left: 50%;
|
||||
bottom: 17px;
|
||||
border-radius: 2px;
|
||||
margin-left: -2px;
|
||||
background-color: #C9DAE1; }
|
||||
.sweet-alert .sa-icon.sa-info::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
margin-left: -3px;
|
||||
top: 19px;
|
||||
background-color: #C9DAE1; }
|
||||
.sweet-alert .sa-icon.sa-success {
|
||||
border-color: #A5DC86; }
|
||||
.sweet-alert .sa-icon.sa-success::before, .sweet-alert .sa-icon.sa-success::after {
|
||||
content: '';
|
||||
-webkit-border-radius: 40px;
|
||||
border-radius: 40px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
height: 120px;
|
||||
background: white;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg); }
|
||||
.sweet-alert .sa-icon.sa-success::before {
|
||||
-webkit-border-radius: 120px 0 0 120px;
|
||||
border-radius: 120px 0 0 120px;
|
||||
top: -7px;
|
||||
left: -33px;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform-origin: 60px 60px;
|
||||
transform-origin: 60px 60px; }
|
||||
.sweet-alert .sa-icon.sa-success::after {
|
||||
-webkit-border-radius: 0 120px 120px 0;
|
||||
border-radius: 0 120px 120px 0;
|
||||
top: -11px;
|
||||
left: 30px;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform-origin: 0px 60px;
|
||||
transform-origin: 0px 60px; }
|
||||
.sweet-alert .sa-icon.sa-success .sa-placeholder {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 4px solid rgba(165, 220, 134, 0.2);
|
||||
-webkit-border-radius: 40px;
|
||||
border-radius: 40px;
|
||||
border-radius: 50%;
|
||||
box-sizing: content-box;
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
z-index: 2; }
|
||||
.sweet-alert .sa-icon.sa-success .sa-fix {
|
||||
width: 5px;
|
||||
height: 90px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
left: 28px;
|
||||
top: 8px;
|
||||
z-index: 1;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg); }
|
||||
.sweet-alert .sa-icon.sa-success .sa-line {
|
||||
height: 5px;
|
||||
background-color: #A5DC86;
|
||||
display: block;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
z-index: 2; }
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-tip {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 46px;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg); }
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-long {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg); }
|
||||
.sweet-alert .sa-icon.sa-custom {
|
||||
background-size: contain;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat; }
|
||||
|
||||
/*
|
||||
* Animations
|
||||
*/
|
||||
@-webkit-keyframes showSweetAlert {
|
||||
0% {
|
||||
transform: scale(0.7);
|
||||
-webkit-transform: scale(0.7); }
|
||||
45% {
|
||||
transform: scale(1.05);
|
||||
-webkit-transform: scale(1.05); }
|
||||
80% {
|
||||
transform: scale(0.95);
|
||||
-webkit-transform: scale(0.95); }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); } }
|
||||
|
||||
@keyframes showSweetAlert {
|
||||
0% {
|
||||
transform: scale(0.7);
|
||||
-webkit-transform: scale(0.7); }
|
||||
45% {
|
||||
transform: scale(1.05);
|
||||
-webkit-transform: scale(1.05); }
|
||||
80% {
|
||||
transform: scale(0.95);
|
||||
-webkit-transform: scale(0.95); }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); } }
|
||||
|
||||
@-webkit-keyframes hideSweetAlert {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); }
|
||||
100% {
|
||||
transform: scale(0.5);
|
||||
-webkit-transform: scale(0.5); } }
|
||||
|
||||
@keyframes hideSweetAlert {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); }
|
||||
100% {
|
||||
transform: scale(0.5);
|
||||
-webkit-transform: scale(0.5); } }
|
||||
|
||||
@-webkit-keyframes slideFromTop {
|
||||
0% {
|
||||
top: 0%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@keyframes slideFromTop {
|
||||
0% {
|
||||
top: 0%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@-webkit-keyframes slideToTop {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 0%; } }
|
||||
|
||||
@keyframes slideToTop {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 0%; } }
|
||||
|
||||
@-webkit-keyframes slideFromBottom {
|
||||
0% {
|
||||
top: 70%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@keyframes slideFromBottom {
|
||||
0% {
|
||||
top: 70%; }
|
||||
100% {
|
||||
top: 50%; } }
|
||||
|
||||
@-webkit-keyframes slideToBottom {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 70%; } }
|
||||
|
||||
@keyframes slideToBottom {
|
||||
0% {
|
||||
top: 50%; }
|
||||
100% {
|
||||
top: 70%; } }
|
||||
|
||||
.showSweetAlert[data-animation=pop] {
|
||||
-webkit-animation: showSweetAlert 0.3s;
|
||||
animation: showSweetAlert 0.3s; }
|
||||
|
||||
.showSweetAlert[data-animation=none] {
|
||||
-webkit-animation: none;
|
||||
animation: none; }
|
||||
|
||||
.showSweetAlert[data-animation=slide-from-top] {
|
||||
-webkit-animation: slideFromTop 0.3s;
|
||||
animation: slideFromTop 0.3s; }
|
||||
|
||||
.showSweetAlert[data-animation=slide-from-bottom] {
|
||||
-webkit-animation: slideFromBottom 0.3s;
|
||||
animation: slideFromBottom 0.3s; }
|
||||
|
||||
.hideSweetAlert[data-animation=pop] {
|
||||
-webkit-animation: hideSweetAlert 0.2s;
|
||||
animation: hideSweetAlert 0.2s; }
|
||||
|
||||
.hideSweetAlert[data-animation=none] {
|
||||
-webkit-animation: none;
|
||||
animation: none; }
|
||||
|
||||
.hideSweetAlert[data-animation=slide-from-top] {
|
||||
-webkit-animation: slideToTop 0.4s;
|
||||
animation: slideToTop 0.4s; }
|
||||
|
||||
.hideSweetAlert[data-animation=slide-from-bottom] {
|
||||
-webkit-animation: slideToBottom 0.3s;
|
||||
animation: slideToBottom 0.3s; }
|
||||
|
||||
@-webkit-keyframes animateSuccessTip {
|
||||
0% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
54% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
70% {
|
||||
width: 50px;
|
||||
left: -8px;
|
||||
top: 37px; }
|
||||
84% {
|
||||
width: 17px;
|
||||
left: 21px;
|
||||
top: 48px; }
|
||||
100% {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 45px; } }
|
||||
|
||||
@keyframes animateSuccessTip {
|
||||
0% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
54% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px; }
|
||||
70% {
|
||||
width: 50px;
|
||||
left: -8px;
|
||||
top: 37px; }
|
||||
84% {
|
||||
width: 17px;
|
||||
left: 21px;
|
||||
top: 48px; }
|
||||
100% {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 45px; } }
|
||||
|
||||
@-webkit-keyframes animateSuccessLong {
|
||||
0% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
65% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
84% {
|
||||
width: 55px;
|
||||
right: 0px;
|
||||
top: 35px; }
|
||||
100% {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px; } }
|
||||
|
||||
@keyframes animateSuccessLong {
|
||||
0% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
65% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px; }
|
||||
84% {
|
||||
width: 55px;
|
||||
right: 0px;
|
||||
top: 35px; }
|
||||
100% {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px; } }
|
||||
|
||||
@-webkit-keyframes rotatePlaceholder {
|
||||
0% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
5% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
12% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); }
|
||||
100% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); } }
|
||||
|
||||
@keyframes rotatePlaceholder {
|
||||
0% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
5% {
|
||||
transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg); }
|
||||
12% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); }
|
||||
100% {
|
||||
transform: rotate(-405deg);
|
||||
-webkit-transform: rotate(-405deg); } }
|
||||
|
||||
.animateSuccessTip {
|
||||
-webkit-animation: animateSuccessTip 0.75s;
|
||||
animation: animateSuccessTip 0.75s; }
|
||||
|
||||
.animateSuccessLong {
|
||||
-webkit-animation: animateSuccessLong 0.75s;
|
||||
animation: animateSuccessLong 0.75s; }
|
||||
|
||||
.sa-icon.sa-success.animate::after {
|
||||
-webkit-animation: rotatePlaceholder 4.25s ease-in;
|
||||
animation: rotatePlaceholder 4.25s ease-in; }
|
||||
|
||||
@-webkit-keyframes animateErrorIcon {
|
||||
0% {
|
||||
transform: rotateX(100deg);
|
||||
-webkit-transform: rotateX(100deg);
|
||||
opacity: 0; }
|
||||
100% {
|
||||
transform: rotateX(0deg);
|
||||
-webkit-transform: rotateX(0deg);
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes animateErrorIcon {
|
||||
0% {
|
||||
transform: rotateX(100deg);
|
||||
-webkit-transform: rotateX(100deg);
|
||||
opacity: 0; }
|
||||
100% {
|
||||
transform: rotateX(0deg);
|
||||
-webkit-transform: rotateX(0deg);
|
||||
opacity: 1; } }
|
||||
|
||||
.animateErrorIcon {
|
||||
-webkit-animation: animateErrorIcon 0.5s;
|
||||
animation: animateErrorIcon 0.5s; }
|
||||
|
||||
@-webkit-keyframes animateXMark {
|
||||
0% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
50% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
80% {
|
||||
transform: scale(1.15);
|
||||
-webkit-transform: scale(1.15);
|
||||
margin-top: -6px; }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
margin-top: 0;
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes animateXMark {
|
||||
0% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
50% {
|
||||
transform: scale(0.4);
|
||||
-webkit-transform: scale(0.4);
|
||||
margin-top: 26px;
|
||||
opacity: 0; }
|
||||
80% {
|
||||
transform: scale(1.15);
|
||||
-webkit-transform: scale(1.15);
|
||||
margin-top: -6px; }
|
||||
100% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
margin-top: 0;
|
||||
opacity: 1; } }
|
||||
|
||||
.animateXMark {
|
||||
-webkit-animation: animateXMark 0.5s;
|
||||
animation: animateXMark 0.5s; }
|
||||
|
||||
@-webkit-keyframes pulseWarning {
|
||||
0% {
|
||||
border-color: #F8D486; }
|
||||
100% {
|
||||
border-color: #F8BB86; } }
|
||||
|
||||
@keyframes pulseWarning {
|
||||
0% {
|
||||
border-color: #F8D486; }
|
||||
100% {
|
||||
border-color: #F8BB86; } }
|
||||
|
||||
.pulseWarning {
|
||||
-webkit-animation: pulseWarning 0.75s infinite alternate;
|
||||
animation: pulseWarning 0.75s infinite alternate; }
|
||||
|
||||
@-webkit-keyframes pulseWarningIns {
|
||||
0% {
|
||||
background-color: #F8D486; }
|
||||
100% {
|
||||
background-color: #F8BB86; } }
|
||||
|
||||
@keyframes pulseWarningIns {
|
||||
0% {
|
||||
background-color: #F8D486; }
|
||||
100% {
|
||||
background-color: #F8BB86; } }
|
||||
|
||||
.pulseWarningIns {
|
||||
-webkit-animation: pulseWarningIns 0.75s infinite alternate;
|
||||
animation: pulseWarningIns 0.75s infinite alternate; }
|
||||
|
||||
/* Internet Explorer 9 has some special quirks that are fixed here */
|
||||
/* The icons are not animated. */
|
||||
/* This file is automatically merged into sweet-alert.min.js through Gulp */
|
||||
/* Error icon */
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-left {
|
||||
-ms-transform: rotate(45deg) \9; }
|
||||
|
||||
.sweet-alert .sa-icon.sa-error .sa-line.sa-right {
|
||||
-ms-transform: rotate(-45deg) \9; }
|
||||
|
||||
/* Success icon */
|
||||
.sweet-alert .sa-icon.sa-success {
|
||||
border-color: transparent\9; }
|
||||
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-tip {
|
||||
-ms-transform: rotate(45deg) \9; }
|
||||
|
||||
.sweet-alert .sa-icon.sa-success .sa-line.sa-long {
|
||||
-ms-transform: rotate(-45deg) \9; }
|
|
@ -4,10 +4,10 @@
|
|||
var checked=false;
|
||||
function check_all(form) {
|
||||
var checkboxes = document.getElementById(form);
|
||||
if (checked == false) {
|
||||
checked = true
|
||||
if (checked === false) {
|
||||
checked = true;
|
||||
} else {
|
||||
checked = false
|
||||
checked = false;
|
||||
}
|
||||
for (var i = 0; i < checkboxes.elements.length; i++) {
|
||||
if (checkboxes.elements[i].type == "checkbox") {
|
||||
|
@ -51,13 +51,13 @@ function GetRowData(row){
|
|||
//此函数用于在多选提交时至少要选择一行
|
||||
function GetTableDataBox() {
|
||||
var tabProduct = document.getElementById("editable");
|
||||
var tableData = new Array();
|
||||
var returnData = new Array();
|
||||
var tableData = [];
|
||||
var returnData = [];
|
||||
var checkboxes = document.getElementById("contents_form");
|
||||
var id_list = new Array();
|
||||
var id_list = [];
|
||||
len = checkboxes.elements.length;
|
||||
for (var i=0; i < len; i++) {
|
||||
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
|
||||
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") {
|
||||
id_list.push(i);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ function GetTableDataBox() {
|
|||
tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
|
||||
}
|
||||
|
||||
if (id_list.length == 0){
|
||||
if (id_list.length === 0){
|
||||
alert('请至少选择一行!');
|
||||
}
|
||||
returnData.push(tableData);
|
||||
|
@ -77,7 +77,7 @@ function GetTableDataBox() {
|
|||
|
||||
function move(from, to, from_o, to_o) {
|
||||
$("#" + from + " option").each(function () {
|
||||
if ($(this).prop("selected") == true) {
|
||||
if ($(this).prop("selected") === true) {
|
||||
$("#" + to).append(this);
|
||||
if( typeof from_o !== 'undefined'){
|
||||
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
|
||||
|
@ -88,7 +88,7 @@ function move(from, to, from_o, to_o) {
|
|||
|
||||
function move_left(from, to, from_o, to_o) {
|
||||
$("#" + from + " option").each(function () {
|
||||
if ($(this).prop("selected") == true) {
|
||||
if ($(this).prop("selected") === true) {
|
||||
$("#" + to).append(this);
|
||||
if( typeof from_o !== 'undefined'){
|
||||
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
|
||||
|
@ -126,8 +126,8 @@ function move_left(from, to, from_o, to_o) {
|
|||
function selectAll(){
|
||||
// 选择该页面所有option
|
||||
$('option').each(function(){
|
||||
$(this).attr('selected', true)
|
||||
})
|
||||
$(this).attr('selected', true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,6 +156,8 @@ function getIDall() {
|
|||
function APIUpdateAttr(props) {
|
||||
// props = {url: .., body: , success: , error: , method: ,}
|
||||
props = props || {};
|
||||
success_message = props.success_message || 'Update Successfully!';
|
||||
fail_message = props.fail_message || 'Error occurred while updating.';
|
||||
$.ajax({
|
||||
url: props.url,
|
||||
type: props.method || "PATCH",
|
||||
|
@ -164,18 +166,18 @@ function APIUpdateAttr(props) {
|
|||
dataType: props.data_type || "json",
|
||||
}).done(function(data, textStatue, jqXHR) {
|
||||
if (typeof props.success === 'function') {
|
||||
return props.success(data)
|
||||
return props.success(data);
|
||||
} else {
|
||||
toastr.success('Update Success!')
|
||||
toastr.success(success_message);
|
||||
}
|
||||
}).fail(function(jqXHR, textStatue, errorThrown) {
|
||||
if (typeof props.error === 'function') {
|
||||
return props.error(errorThrown)
|
||||
return props.error(errorThrown);
|
||||
} else {
|
||||
toastr.error('Error occurred while updating.')
|
||||
toastr.error(fail_message);
|
||||
}
|
||||
})
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
var jumpserver = new Object();
|
||||
var jumpserver = {};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,20 @@
|
|||
{% load i18n %}
|
||||
<div aria-hidden="true" role="dialog" tabindex="-1" id="{% block modal_id %}{% endblock %}" class="modal inmodal" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content animated fadeIn">
|
||||
<div class="modal-header">
|
||||
<button data-dismiss="modal" class="close" type="button"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
<h4 class="modal-title">{% block modal_title %}{% endblock %}</h4>
|
||||
<small>{% block modal_comment %}{% endblock %}</small>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% block modal_body %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button data-dismiss="modal" class="btn btn-white" type="button">{% trans "Close" %}</button>
|
||||
<button class="btn btn-primary" type="button" id="{% block modal_confirm_id %}{% endblock %}">{% trans 'Confirm' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -6,6 +6,7 @@ import logging
|
|||
from rest_framework import generics
|
||||
|
||||
from .serializers import UserSerializer, UserGroupSerializer, UserAttributeSerializer, UserGroupEditSerializer
|
||||
from .serializers import UserPKUpdateSerializer
|
||||
from .models import User, UserGroup
|
||||
|
||||
|
||||
|
@ -49,3 +50,25 @@ class UserAttributeApi(generics.RetrieveUpdateDestroyAPIView):
|
|||
class UserGroupEditApi(generics.RetrieveUpdateAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserGroupEditSerializer
|
||||
|
||||
|
||||
class UserResetPasswordApi(generics.UpdateAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserGroupEditSerializer
|
||||
|
||||
def perform_update(self, serializer):
|
||||
# Note: we are not updating the user object here.
|
||||
# We just do the reset-password staff.
|
||||
user = self.get_object()
|
||||
from .utils import send_reset_password_mail
|
||||
send_reset_password_mail(user)
|
||||
|
||||
|
||||
class UserResetPKApi(generics.UpdateAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserPKUpdateSerializer
|
||||
|
||||
def perform_update(self, serializer):
|
||||
user = self.get_object()
|
||||
user.private_key = serializer.validated_data['_private_key']
|
||||
user.save()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import User, UserGroup
|
||||
|
@ -38,3 +40,17 @@ class UserGroupEditSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = User
|
||||
fields = ['id', 'groups']
|
||||
|
||||
|
||||
class UserPKUpdateSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['id', '_private_key']
|
||||
|
||||
def validate__private_key(self, value):
|
||||
from users.utils import validate_ssh_pk
|
||||
checked, reason = validate_ssh_pk(value)
|
||||
if not checked:
|
||||
raise serializers.ValidationError(_('Not a valid ssh private key.'))
|
||||
return value
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{% extends '_modal.html' %}
|
||||
{% load i18n %}
|
||||
{% block modal_id %}user_reset_pk_modal{% endblock %}
|
||||
{% block modal_title%}{% trans 'Reset User SSH Private Key' %}{% endblock %}
|
||||
{% block modal_body %}
|
||||
<textarea id="txt_pk" class="form-control" cols="30" rows="10" placeholder="-----BEGIN RSA PRIVATE KEY-----"></textarea>
|
||||
{% endblock %}
|
||||
{% block modal_confirm_id %}btn_user_reset_pk{% endblock %}
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
|
||||
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
||||
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
|
@ -114,8 +116,8 @@
|
|||
<table class="table">
|
||||
<tbody>
|
||||
<tr class="no-borders-tr">
|
||||
<td width="50%">Active:</td>
|
||||
<td><span style="float: right">
|
||||
<td width="50%">{% trans 'Active' %}:</td>
|
||||
<td><span class="pull-right">
|
||||
<div class="switch">
|
||||
<div class="onoffswitch">
|
||||
<input type="checkbox" {% if user_object.is_active %} checked {% endif %} class="onoffswitch-checkbox" id="is_active">
|
||||
|
@ -128,8 +130,8 @@
|
|||
</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>二次验证:</td>
|
||||
<td><span style="float: right">
|
||||
<td>{% trans 'Enable OTP' %}:</td>
|
||||
<td><span class="pull-right">
|
||||
<div class="switch">
|
||||
<div class="onoffswitch">
|
||||
<input type="checkbox" class="onoffswitch-checkbox" {% if user_object.enable_otp %} checked {% endif %}
|
||||
|
@ -145,16 +147,16 @@
|
|||
<tr>
|
||||
<td>{% trans 'Reset password' %}:</td>
|
||||
<td>
|
||||
<span style="float: right">
|
||||
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Reset' %}</button>
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_password" style="width: 54px">{% trans 'Reset' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Reset ssh key' %}:</td>
|
||||
<td>
|
||||
<span style="float: right">
|
||||
<button type="button" class="btn btn-primary btn-xs" style="width: 54px;">{% trans 'Reset' %}</button>
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_pk" style="width: 54px;" data-toggle="modal" data-target="#user_reset_pk_modal">{% trans 'Reset' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -191,7 +193,7 @@
|
|||
<tr>
|
||||
<td ><b class="bdg_user_group" data-gid={{ group.id }}>{{ group.name }}</b></td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-sm btn_delete_user_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
||||
<button class="btn btn-danger pull-right btn-sm btn_delete_user_group" type="button"><i class="fa fa-minus"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -205,6 +207,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'users/_user_reset_pk_modal.html' %}
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
|
@ -225,13 +228,13 @@ function updateUserGroups(user_groups) {
|
|||
$('.group_edit tbody').append(
|
||||
'<tr>' +
|
||||
'<td><b class="bdg_user_group" data-gid="' + index + '">' + group_name + '</b></td>' +
|
||||
'<td><button class="btn btn-danger btn-sm btn_delete_user_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button></td>' +
|
||||
'<td><button class="btn btn-danger btn-sm pull-right btn_delete_user_group" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||
'</tr>'
|
||||
)
|
||||
});
|
||||
// clear jumpserver.selected_groups
|
||||
jumpserver.selected_groups = {};
|
||||
toastr.success('{% trans "Update success!" %}')
|
||||
toastr.success('{% trans "UserGroup Update Success!" %}')
|
||||
};
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, method: 'PUT'});
|
||||
|
||||
|
@ -249,18 +252,14 @@ $(document).ready(function () {
|
|||
var the_url = "{% url 'users:user-patch-api' pk=user_object.id %}";
|
||||
var checked = !$(this).prop('checked');
|
||||
var body = {'is_active': checked };
|
||||
var success = function() {
|
||||
toastr.success('{% trans "Update success!" %}')
|
||||
};
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success});
|
||||
var success = '{% trans "Update Successfully!" %}';
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success_message: success});
|
||||
}).on('click', '#enable_otp', function(){
|
||||
var the_url = "{% url 'users:user-patch-api' pk=user_object.id %}";
|
||||
var checked = !$(this).prop('checked');
|
||||
var body = {'enable_otp': checked };
|
||||
var success = function() {
|
||||
toastr.success('{% trans "Update success!" %}')
|
||||
};
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success});
|
||||
var success = '{% trans "Update Successfully!" %}';
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success_message: success});
|
||||
}).on('click', '#btn_add_user_group', function(){
|
||||
if (Object.keys(jumpserver.selected_groups).length === 0) {
|
||||
return false;
|
||||
|
@ -287,6 +286,56 @@ $(document).ready(function () {
|
|||
return $(this).data('gid');
|
||||
}).get();
|
||||
updateUserGroups(user_groups)
|
||||
}).on('click', '#btn_reset_password', function(){
|
||||
function doReset() {
|
||||
var the_url = '{% url "users:user-reset-password-api" pk=user_object.id %}';
|
||||
var body = {};
|
||||
var success = function() {
|
||||
var msg = "{% trans 'E-mail sent successfully. An e-mail has been sent to the user\'s mailbox.' %}";
|
||||
swal("{% trans 'Password-Reset' %}", msg, "success");
|
||||
}
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success});
|
||||
}
|
||||
swal({
|
||||
title: "{% trans 'Are you sure?' %}",
|
||||
text: "{% trans 'This will reset the user\'s password.' %}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: false
|
||||
}, function () {
|
||||
doReset();
|
||||
}
|
||||
);
|
||||
}).on('click', '#btn_user_reset_pk', function(){
|
||||
var $this = $(this);
|
||||
var pk = $('#txt_pk').val();
|
||||
var the_url = '{% url "users:user-reset-pk-api" pk=user_object.id %}';
|
||||
var body = {'_private_key': pk};
|
||||
var success = function() {
|
||||
$('#txt_pk').val('');
|
||||
$this.closest('.modal').modal('hide');
|
||||
var msg = "{% trans 'Successfully updated the SSH private key.' %}";
|
||||
swal("{% trans 'User SSH Private Key Reset' %}", msg, "success");
|
||||
};
|
||||
var fail = function() {
|
||||
var msg = "{% trans 'Failed to update the user\'s SSH private key.' %}";
|
||||
swal({
|
||||
title: "{% trans 'User SSH Private Key Reset' %}",
|
||||
text: msg,
|
||||
type: "error",
|
||||
showCancelButton: false,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: true
|
||||
}, function () {
|
||||
$('#txt_pk').focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, error: fail});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -35,6 +35,8 @@ urlpatterns += [
|
|||
api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
|
||||
url(r'^v1/users/(?P<pk>[0-9]+)/patch$',
|
||||
api.UserAttributeApi.as_view(), name='user-patch-api'),
|
||||
url(r'^v1/users/(?P<pk>\d+)/reset-password/$', api.UserResetPasswordApi.as_view(), name='user-reset-password-api'),
|
||||
url(r'^v1/users/(?P<pk>\d+)/reset-pk/$', api.UserResetPKApi.as_view(), name='user-reset-pk-api'),
|
||||
url(r'^v1/user-groups$', api.UserGroupListAddApi.as_view(), name='user-group-list-api'),
|
||||
url(r'^v1/user-groups/(?P<pk>[0-9]+)$',
|
||||
api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
|
||||
|
|
|
@ -5,6 +5,7 @@ import logging
|
|||
import os
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext as _
|
||||
|
@ -121,6 +122,8 @@ def send_reset_password_mail(user):
|
|||
'email': user.email,
|
||||
'login_url': reverse('users:login', external=True),
|
||||
}
|
||||
if settings.DEBUG:
|
||||
logger.debug(message)
|
||||
|
||||
send_mail_async.delay(subject, message, recipient_list, html_message=message)
|
||||
|
||||
|
|
Loading…
Reference in New Issue