related to #2165 new add user popin

- add field for add user
- in the `pwg.users.add` method, the params `send_password_by_mail` does nothing anymore. Because we no longer want to send passwords in clear text.
- in the `pwg.users.add` add a new `auto_password` parameter to generate a random password when a user is created
- use this parameter (`auto_password`) in user_list.js
- change mail content et password page on first login
This commit is contained in:
Linty 2024-06-28 18:49:34 +02:00
parent 834b339860
commit c8d7503d4e
9 changed files with 385 additions and 119 deletions

View file

@ -55,6 +55,7 @@ jQuery('[data-selectize=groups]').selectize({
let groupSelectize = jQuery('[data-selectize=groups]')[0].selectize; let groupSelectize = jQuery('[data-selectize=groups]')[0].selectize;
let groupGuestSelectize = jQuery('[data-selectize=groups]')[1].selectize; let groupGuestSelectize = jQuery('[data-selectize=groups]')[1].selectize;
let groupAddUserSelectize = $('[data-selectize=groups]')[2].selectize;
/*----------------- /*-----------------
OnClick functions OnClick functions
@ -149,18 +150,6 @@ $( document ).ready(function() {
$('.edit-guest-user-button').click(open_guest_user_list); $('.edit-guest-user-button').click(open_guest_user_list);
$('.CloseGuestUserList').click(close_guest_user_list); $('.CloseGuestUserList').click(close_guest_user_list);
$('#GuestUserList .close-update-button').click(close_guest_user_list); $('#GuestUserList .close-update-button').click(close_guest_user_list);
$("#show_password").click(function() {
if ($(this).hasClass("icon-eye")) {
$(this).removeClass("icon-eye");
$(this).addClass("icon-eye-off");
$("#AddUserPassword").get(0).type = "text";
} else {
$(this).removeClass("icon-eye-off");
$(this).addClass("icon-eye");
$("#AddUserPassword").get(0).type = "password";
}
})
/* Action */ /* Action */
jQuery("[id^=action_]").hide(); jQuery("[id^=action_]").hide();
@ -180,10 +169,6 @@ $( document ).ready(function() {
$(this).siblings().attr("data-selected", "0"); $(this).siblings().attr("data-selected", "0");
} }
}) })
$(".AddUserGenPassword").on('click', function() {
const password = gen_password();
$("#AddUserPassword").val(password);
});
$('.EditUserGenPassword').on('click', function() { $('.EditUserGenPassword').on('click', function() {
const password = gen_password(); const password = gen_password();
$('#edit_user_password').val(password); $('#edit_user_password').val(password);
@ -818,7 +803,10 @@ function add_user_close() {
} }
function add_user_open() { function add_user_open() {
$('#AddUser .AddUserInput').val(''); $('#AddUserSuccessContainer').hide();
$('#AddUserFieldContainer').show();
$('#AddUser :input').val('');
fill_new_user();
$("#AddUser").fadeIn(); $("#AddUser").fadeIn();
$(".AddUserLabelUsername input").first().focus(); $(".AddUserLabelUsername input").first().focus();
} }
@ -1429,7 +1417,7 @@ function fill_user_edit_summary(user_to_edit, pop_in, isGuest) {
$('#copy_password').hide(); $('#copy_password').hide();
$('.update-password-success').css('margin', '40px 0'); $('.update-password-success').css('margin', '40px 0');
$('#result_send_mail_copy').hide(); $('#result_send_mail_copy').hide();
$('#result_send_mail_copy_btn') $('#result_send_mail_copy_btn, #AddUserCopyPassword')
.css({'cursor': 'not-allowed', 'background-color' : 'grey', 'color': '#ffffff'}) .css({'cursor': 'not-allowed', 'background-color' : 'grey', 'color': '#ffffff'})
.attr('title', cantCopy) .attr('title', cantCopy)
.on('mouseenter', function() { .on('mouseenter', function() {
@ -1680,6 +1668,27 @@ function fill_guest_edit() {
fill_user_edit_update(user_to_edit, pop_in); fill_user_edit_update(user_to_edit, pop_in);
} }
function fill_new_user() {
// When you want to add an user: privacy level and groups
// by default are the same as Guest, not status
const addUserPopIn = $('#AddUser');
const status_index = get_status_index('normal');
const level_index = get_level_index(guest_user.level);
set_selected_groups(guest_user.groups);
groupAddUserSelectize.clear();
groupAddUserSelectize.load(function(callback) {
callback(groupOptions);
});
jQuery.each(jQuery.grep(groupOptions, function(group) {
return group.isSelected;
}), function(i, group) {
groupAddUserSelectize.addItem(group.value);
});
addUserPopIn.find(`.user-property-status select option:eq(${status_index})`).prop("selected", true);
addUserPopIn.find(`.user-property-level select option:eq(${level_index})`).prop("selected", true);
addUserPopIn.find('.user-list-checkbox[name="hd_enabled"]').attr('data-selected', guest_user.enabled_high == 'true' ? '1' : '0');
}
function fill_who_is_the_king(user_to_edit, pop_in) { function fill_who_is_the_king(user_to_edit, pop_in) {
const who_is_the_king = pop_in.find("#who_is_the_king"); const who_is_the_king = pop_in.find("#who_is_the_king");
// By default I'm an admin and I only see who is the Main User // By default I'm an admin and I only see who is the Main User
@ -2115,17 +2124,30 @@ function update_user_list() {
} }
function add_user() { function add_user() {
let ajax_data = { let ajax_data = {};
pwg_token: pwg_token, let groups_selected = $('.AddUserInputContainer .user-property-group .selectize-input .item').map(function () {
} return parseInt($(this).attr('data-value'));
} ).get();
ajax_data.username = $('.AddUserLabelUsername .user-property-input').val(); ajax_data.username = $('.AddUserLabelUsername .user-property-input').val();
ajax_data.password = $('#AddUserPassword').val();
ajax_data.email = $(".AddUserLabelEmail .user-property-input").val(); ajax_data.email = $(".AddUserLabelEmail .user-property-input").val();
ajax_data.send_password_by_mail = $('.user-list-checkbox[name="send_by_email"]').attr("data-selected") == "1" ? true : false; ajax_data.status = $(".AddUserInputContainer .user-property-status select").val();
jQuery.ajax({ ajax_data.level = $(".AddUserInputContainer .user-property-level select").val();
ajax_data.enabled_high = $(".AddUserInputContainer .user-list-checkbox[name=\"hd_enabled\"]").attr('data-selected') == '1' ? true : false;
ajax_data.group_id = groups_selected.length == 0 ? -1 : groups_selected;
ajax_data.auto_password = true;
// for debug
// console.log(ajax_data);
$.ajax({
url: "ws.php?format=json&method=pwg.users.add", url: "ws.php?format=json&method=pwg.users.add",
type:"POST", type:"POST",
data: ajax_data, data: {
username: ajax_data.username,
auto_password: true,
email: ajax_data.email,
pwg_token
},
beforeSend: function() { beforeSend: function() {
$("#AddUser .AddUserErrors").css("visibility", "hidden"); $("#AddUser .AddUserErrors").css("visibility", "hidden");
if ($(".AddUserLabelUsername .user-property-input").val() == "") { if ($(".AddUserLabelUsername .user-property-input").val() == "") {
@ -2136,12 +2158,41 @@ function add_user() {
}, },
success: (raw_data) => { success: (raw_data) => {
let data = jQuery.parseJSON(raw_data); let data = jQuery.parseJSON(raw_data);
if (data.stat == 'ok') {
let new_user_id = data.result.users[0].id;
add_infos_to_new_user(new_user_id, ajax_data);
}
else {
$("#AddUser .AddUserErrors").html(data.message)
$("#AddUser .AddUserErrors").css("visibility", "visible");
}
}
});
}
function add_infos_to_new_user(user_id, ajax_data) {
$.ajax({
url: 'ws.php?format=json&method=pwg.users.setInfo',
type: 'POST',
data: {
user_id,
status: ajax_data.status,
level: ajax_data.level,
group_id: ajax_data.group_id,
enabled_high: ajax_data.enabled_high,
pwg_token
},
success: function(response) {
const data = JSON.parse(response);
if (data.stat == 'ok') { if (data.stat == 'ok') {
let new_user_id = data.result.users[0].id; let new_user_id = data.result.users[0].id;
update_user_list(); update_user_list();
add_user_close(); // add_user_close();
$('#AddUserUpdated').removeClass('icon-red icon-cancel').addClass('icon-green border-green icon-ok');
$('#AddUserUpdatedText').html(user_added_str.replace("%s", ajax_data.username));
send_new_user_password(new_user_id, ajax_data.email === '' ? false : true);
$("#AddUser .user-property-input").val(""); $("#AddUser .user-property-input").val("");
$("#AddUserSuccess .edit-now").unbind("click").click(() => { $("#AddUserSuccess .edit-now").off("click").on("click", () => {
last_user_id = new_user_id; last_user_id = new_user_id;
last_user_index = get_container_index_from_uid(new_user_id); last_user_index = get_container_index_from_uid(new_user_id);
if (last_user_index != -1) { if (last_user_index != -1) {
@ -2163,6 +2214,53 @@ function add_user() {
}); });
} }
function send_new_user_password(user_id, send_by_mail) {
$.ajax({
url: "ws.php?format=json",
dataType: "json",
data:{
method: 'pwg.users.generateResetPasswordLink',
user_id: user_id,
send_by_mail: send_by_mail,
pwg_token: pwg_token
},
success: function(response) {
if('ok' === response.stat) {
$('#AddUserFieldContainer').hide();
$('#AddUserSuccessContainer').fadeIn();
$('#AddUserPasswordLink').val(response.result.generated_link).trigger('focus');
$('#AddUserTextField').html(send_by_mail ? validLinkMail : validLinkWithoutMail);
if(send_by_mail && !response.result.send_by_mail) {
$('#AddUserUpdated').removeClass('icon-green border-green icon-ok').addClass('icon-red-error icon-cancel');
$('#AddUserUpdatedText').html(errorMailSent);
}
if (window.isSecureContext && navigator.clipboard) {
$('#AddUserCopyPassword').off('click').on('click', function() {
const successMsg = $('#AddUserUpdatedText');
successMsg.fadeOut();
copyToClipboard(response.result.generated_link);
$('#AddUserUpdated').removeClass('icon-red icon-cancel').addClass('icon-green border-green icon-ok');
successMsg.html(copyLinkStr);
successMsg.fadeIn();
});
};
$('#AddUserButton').off('click').on('click', function() {
add_user_close();
});
} else {
$('#AddUserUpdated').removeClass('icon-green border-green icon-ok').addClass('icon-red-error icon-cancel');
$('#AddUserUpdatedText').html(response.message);
}
},
error: function(response) {
$('#AddUserUpdated').removeClass('icon-green border-green icon-ok').addClass('icon-red-error icon-cancel');
$('#AddUserUpdatedText').html(response.message);
}
});
}
function delete_user(uid) { function delete_user(uid) {
jQuery.ajax({ jQuery.ajax({
url: "ws.php?format=json&method=pwg.users.delete", url: "ws.php?format=json&method=pwg.users.delete",

View file

@ -45,6 +45,8 @@ const mainUserUpgradeWebmaster = "{'This user must first be defined as the webma
const errorStr = "{'an error happened'|@translate|escape:javascript}"; const errorStr = "{'an error happened'|@translate|escape:javascript}";
const copyLinkStr = "{'Copied link'|@translate|escape:javascript}"; const copyLinkStr = "{'Copied link'|@translate|escape:javascript}";
const cantCopy = "{'You cannot copy the password if the connection to this site is not secure.'|@translate|escape:javascript}"; const cantCopy = "{'You cannot copy the password if the connection to this site is not secure.'|@translate|escape:javascript}";
const validLinkMail = "{'A link, valid for 3 days has already been sent. If the email fails, copy the link below and send it to the user so the password can be set.'|@translate|escape:javascript}";
const validLinkWithoutMail = "{'Copy the link below and send it to the user so the password can be set'|@translate|escape:javascript}";
const registered_str = '{"Registered"|@translate|escape:javascript}'; const registered_str = '{"Registered"|@translate|escape:javascript}';
const last_visit_str = '{"Last visit"|@translate|escape:javascript}'; const last_visit_str = '{"Last visit"|@translate|escape:javascript}';
@ -1130,47 +1132,104 @@ $(document).ready(function() {
<div class="AddIconTitle"> <div class="AddIconTitle">
<span>{'Add a new user'|@translate}</span> <span>{'Add a new user'|@translate}</span>
</div> </div>
<div class="AddUserInputContainer">
<label class="user-property-label AddUserLabelUsername">{'Username'|@translate}
<input class="user-property-input" />
</label>
</div>
<div class="AddUserInputContainer"> <div id="AddUserFieldContainer">
<div class="AddUserPasswordWrapper"> <div class="AddUserInputContainer">
<label for="AddUserPassword" class="user-property-label AddUserLabelPassword">{'Password'|@translate}</label> <label class="user-property-label AddUserLabelUsername">{'Username'|@translate}
<span id="show_password" class="icon-eye"></span> <input class="user-property-input" />
</label>
</div> </div>
<input id="AddUserPassword" class="user-property-input" type="password"/>
<div class="AddUserGenPassword"> <div class="AddUserInputContainer">
<span class="icon-dice-solid"></span><span>{'Generate random password'|@translate}</span> <label class="user-property-label AddUserLabelEmail">{'Email'|@translate}
<input class="user-property-input" />
</label>
</div>
<div class="AddUserInputContainer">
<div class="user-property-status">
<label class="user-property-label">{'Status'|@translate}
<span class="icon-help-circled" title="
<div class='tooltip-status-content'>
<div class='tooltip-status-row'><span class='tooltip-col1'>{'user_status_webmaster'|translate}</span><span class='tooltip-col2'>{'Has access to all administration functionnalities. Can manage both configuration and content.'|translate}</span></div>
<div class='tooltip-status-row'><span class='tooltip-col1'>{'user_status_admin'|translate}</span><span class='tooltip-col2'>{'Has access to administration. Can only manage content: photos/albums/users/tags/groups.'|translate}</span></div>
<div class='tooltip-status-row'><span class='tooltip-col1'>{'user_status_normal'|translate}</span><span class='tooltip-col2'>{'No access to administration, can see private content with appropriate permissions.'|translate}</span></div>
<div class='tooltip-status-row'><span class='tooltip-col1'>{'user_status_generic'|translate}</span><span class='tooltip-col2'>{'Can be shared by several individuals without conflict (they cannot change the password).'|translate}</span></div>
<div class='tooltip-status-row'><span class='tooltip-col1'>{'user_status_guest'|translate}</span><span class='tooltip-col2'>{'Equivalent to deactivation. The user is still in the list, but can no longer log in.'|translate}</span></div>
</div">
</span>
</label>
<div class="user-property-select-container">
<select name="status" class="user-property-select">
<option value="webmaster">{'user_status_webmaster'|@translate}</option>
<option value="admin">{'user_status_admin'|@translate}</option>
<option value="normal">{'user_status_normal'|@translate}</option>
<option value="generic">{'user_status_generic'|@translate}</option>
<option value="guest">{'user_status_guest'|@translate} ({'Deactivated'|@translate})</option>
</select>
</div>
</div>
</div>
<div class="AddUserInputContainer">
<div class="user-property-level">
<p class="user-property-label">{'Privacy level'|@translate}</p>
<div class="user-property-select-container">
<select name="privacy" class="user-property-select">
<option value="0">{'Level 0'|@translate}</option>
<option value="1">{'Level 1'|@translate}</option>
<option value="2">{'Level 2'|@translate}</option>
<option value="4">{'Level 4'|@translate}</option>
<option value="8">{'Level 8'|@translate}</option>
</select>
</div>
</div>
</div>
<div class="AddUserInputContainer">
<div class="user-property-group-container">
<p class="user-property-label">{'Groups'|@translate}</p>
<div class="user-property-select-container user-property-group">
<select class="user-property-select" data-selectize="groups"
placeholder="{'Select groups or type them'|translate}" name="group_id[]" multiple
style="box-sizing:border-box;"></select>
</div>
</div>
</div>
<div class="AddUserInputContainer">
<div class="user-list-checkbox" name="hd_enabled">
<span class="select-checkbox">
<i class="icon-ok"></i>
</span>
<span class="user-list-checkbox-label">{'High definition enabled'|translate}</span>
</div>
</div>
<div class="AddUserErrors icon-cancel">
</div>
<div class="AddUserSubmitContainer">
<div class="AddUserCancel">
<span>{'Cancel'|@translate}</span>
</div>
<div class="AddUserSubmit">
<span class="icon-plus"></span><span>{'Add User'|@translate}</span>
</div>
</div> </div>
</div> </div>
<div class="AddUserInputContainer"> <div id="AddUserSuccessContainer" style="display: none;">
<label class="user-property-label AddUserLabelEmail">{'Email'|@translate} <p class="icon-green border-green icon-ok AddUserResult" id="AddUserUpdated"> <span id="AddUserUpdatedText">{'User updated'|@translate}</span></p>
<input class="user-property-input" /> <p class="AddUserTextField" id="AddUserTextField">A link, valid for 3 days has already been sent. If the email fails, copy the link below and send it to the user so the password can be set.</p>
</label> <div class="AddUserPasswordInputContainer">
<input class="AddUserPasswordInput" id="AddUserPasswordLink" />
<span class="icon-docs" id="AddUserCopyPassword"></span>
</div>
<p class="icon-button" id="AddUserButton"><span class="icon-ok"></span> {'Ok'|@translate}</p>
</div> </div>
<div class="user-list-checkbox" name="send_by_email">
<span class="select-checkbox">
<i class="icon-ok"></i>
</span>
<span class="user-list-checkbox-label">{'Send connection settings by email'|translate}</span>
</div>
<div class="AddUserErrors icon-cancel">
</div>
<div class="AddUserSubmit">
<span class="icon-plus"></span><span>{'Add User'|@translate}</span>
</div>
<div class="AddUserCancel" style="display:none;">
<span>{'Cancel'|@translate}</span>
</div>
</div> </div>
</div> </div>
@ -1181,13 +1240,6 @@ $(document).ready(function() {
cursor: help; cursor: help;
} }
#show_password {
position: absolute;
left: 240px;
top: 29px;
z-index: 100; {*used to fix firefox auto fill input*}
}
/* general */ /* general */
.no-flex-grow { .no-flex-grow {
flex-grow:0 !important; flex-grow:0 !important;
@ -1754,6 +1806,10 @@ $(document).ready(function() {
margin-bottom:5px; margin-bottom:5px;
} }
#AddUser .user-property-label {
margin-top: 0;
}
.user-property-label span, .user-property-label span,
.dates-infos { .dates-infos {
color: #ff7700; color: #ff7700;
@ -1833,6 +1889,10 @@ $(document).ready(function() {
margin-left: 418px; margin-left: 418px;
} }
#AddUser .user-property-select-container::before {
margin-left: 328px;
}
.user-action-select-container { .user-action-select-container {
position:relative; position:relative;
} }
@ -1856,6 +1916,12 @@ $(document).ready(function() {
cursor:pointer; cursor:pointer;
} }
#AddUser .user-list-checkbox {
margin-top: 5px;
margin-bottom: 5px;
align-self: start;
}
/* summary section */ /* summary section */
.edit-user-icons { .edit-user-icons {
width: 100%; width: 100%;
@ -1975,7 +2041,8 @@ $(document).ready(function() {
width: 100%; width: 100%;
} }
.user-property-password-choice .head-button-2 { .user-property-password-choice .head-button-2,
#AddUserSuccessContainer .head-button-2 {
display: block; display: block;
text-align: center; text-align: center;
margin-right: 0; margin-right: 0;
@ -1997,7 +2064,8 @@ $(document).ready(function() {
padding-top: 30px; padding-top: 30px;
} }
.edit-password-success .edit-password-success-input { .edit-password-success .edit-password-success-input,
.AddUserPasswordInput {
background-color: transparent; background-color: transparent;
font-size: 15px; font-size: 15px;
border: none; border: none;
@ -2005,7 +2073,8 @@ $(document).ready(function() {
padding: 0 5px; padding: 0 5px;
} }
.edit-password-success .edit-password-success-reset-link { .edit-password-success .edit-password-success-reset-link,
.AddUserPasswordInputContainer {
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%; width: 100%;
@ -2013,12 +2082,14 @@ $(document).ready(function() {
background-color: #F3F3F3; background-color: #F3F3F3;
} }
.edit-password-success .edit-password-success-reset-link span { .edit-password-success .edit-password-success-reset-link span,
.AddUserPasswordInputContainer span {
padding: 5px; padding: 5px;
cursor: pointer; cursor: pointer;
} }
.edit-password-success .edit-password-success-reset-link span:hover { .edit-password-success .edit-password-success-reset-link span:hover,
.AddUserPasswordInputContainer span:hover {
color: #ffffff; color: #ffffff;
background-color: #ff7700; background-color: #ff7700;
} }
@ -2070,7 +2141,8 @@ $(document).ready(function() {
.edit-password-success-ok .icon-button, .edit-password-success-ok .icon-button,
.edit-username-success-ok .icon-button, .edit-username-success-ok .icon-button,
.user-property-main-user-close .icon-button { .user-property-main-user-close .icon-button,
#AddUserSuccessContainer .icon-button {
padding: 10px 20px; padding: 10px 20px;
font-size: 1.1em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
@ -2079,16 +2151,22 @@ $(document).ready(function() {
color: #777; color: #777;
} }
#AddUserSuccessContainer .icon-button {
align-self: center;
}
.edit-password-success-ok .icon-button:hover, .edit-password-success-ok .icon-button:hover,
.edit-username-success-ok .icon-button:hover, .edit-username-success-ok .icon-button:hover,
.user-property-main-user-close .icon-button:hover { .user-property-main-user-close .icon-button:hover,
#AddUserSuccessContainer .icon-button:hover {
background-color: #ddd; background-color: #ddd;
color: #3A3A3A; color: #3A3A3A;
} }
.edit-password-success-ok .icon-button::before, .edit-password-success-ok .icon-button::before,
.edit-username-success-ok .icon-button::before, .edit-username-success-ok .icon-button::before,
.user-property-main-user-close .icon-button::before { .user-property-main-user-close .icon-button::before,
#AddUserSuccessContainer .icon-button::before {
margin-left: 0; margin-left: 0;
} }
@ -2509,7 +2587,32 @@ $(document).ready(function() {
flex-direction:column; flex-direction:column;
border-radius:15px; border-radius:15px;
align-items:center; align-items:center;
width: 270px; width: 350px;
}
#AddUserFieldContainer {
width: 100%;
}
#AddUserSuccessContainer {
display: flex;
flex-direction: column;
width: 100%;
text-align: center;
}
.AddUserPasswordInputContainer {
margin: 0;
}
.AddUserSubmitContainer {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.AddUserTextField {
margin: 0 0 10px 0;
} }
.AddIconContainer { .AddIconContainer {
@ -2533,7 +2636,7 @@ $(document).ready(function() {
.AddUserInputContainer { .AddUserInputContainer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 20px 0px; margin: 5px 0px;
width:100%; width:100%;
} }
@ -2548,38 +2651,8 @@ $(document).ready(function() {
padding: 10px 5px; padding: 10px 5px;
} }
.AddUserPasswordWrapper {
display:flex;
justify-content:space-between;
position: relative;
}
.AddUserPasswordWrapper span {
font-size:1.3em;
cursor:pointer;
}
.AddUserPasswordWrapper:hover {
color:#ffa646;
}
.AddUserGenPassword {
margin-top: 5px;
font-size: 1.1em;
cursor:pointer;
}
.AddUserGenPassword:hover, .AddUserGenPassword:active {
color:#ffa646;
}
.AddUserGenPassword span {
margin-right:10px;
}
.AddUserErrors { .AddUserErrors {
visibility:hidden; visibility:hidden;
width:100%;
padding:5px; padding:5px;
border-left:solid 3px red; border-left:solid 3px red;
} }
@ -2590,29 +2663,37 @@ $(document).ready(function() {
color: #3F3E40; color: #3F3E40;
background-color: #FFA836; background-color: #FFA836;
padding: 10px; padding: 10px;
margin: 20px; margin-top: 5px;
font-size:1em; font-size:1em;
margin-bottom:0; margin-bottom:0;
} }
.AddUserCancel { .AddUserCancel {
color: #3F3E40; color: #A4A4A4;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
font-size:1em; font-size:1em;
} }
.AddUserResult {
padding: 10px;
text-align: start;
}
/* Selectize Inputs (groups) */ /* Selectize Inputs (groups) */
#UserList .user-property-group .selectize-input, #UserList .user-property-group .selectize-input,
#GuestUserList .user-property-group .selectize-input { #GuestUserList .user-property-group .selectize-input,
#AddUser .user-property-group .selectize-input {
overflow-y: scroll; overflow-y: scroll;
} }
#UserList .item, #UserList .item,
#UserList .item.active, #UserList .item.active,
#GuestUserList .item, #GuestUserList .item,
#GuestUserList .item.active { #GuestUserList .item.active,
#AddUser .item,
#AddUser .item.active {
background-image:none; background-image:none;
background-color: #ffa646; background-color: #ffa646;
border-color: transparent; border-color: transparent;
@ -2621,7 +2702,8 @@ $(document).ready(function() {
} }
#UserList .item .remove, #UserList .item .remove,
#GuestUserList .item .remove { #GuestUserList .item .remove,
#AddUser .item .remove {
background-color: transparent; background-color: transparent;
border-top-right-radius: 20px; border-top-right-radius: 20px;
border-bottom-right-radius: 20px; border-bottom-right-radius: 20px;
@ -2630,7 +2712,8 @@ $(document).ready(function() {
} }
#UserList .item .remove:hover, #UserList .item .remove:hover,
#GuestUserList .item .remove:hover { #GuestUserList .item .remove:hover,
#AddUser .item .remove:hover {
background-color: #ff7700; background-color: #ff7700;
} }

View file

@ -5618,7 +5618,7 @@ input:checked + .slider:before, input:checked + .slider::after {
position: relative; position: relative;
} }
.AddUserErrors, .update-user-fail, .AddAlbumErrors, .EditUserErrors, .update-password-fail { .AddUserErrors, .update-user-fail, .AddAlbumErrors, .EditUserErrors, .update-password-fail, .icon-red-error {
background-color: #ffcfcf; background-color: #ffcfcf;
color: #ff5252; color: #ff5252;
border-left:solid 3px red; border-left:solid 3px red;
@ -5635,7 +5635,8 @@ input:checked + .slider:before, input:checked + .slider::after {
} }
.update-user-success, .update-user-success,
.update-password-success, .update-password-success,
.update-username-success { .update-username-success,
.border-green {
border-left: 2px solid #00FF00; border-left: 2px solid #00FF00;
} }
#UserList .AddUserBlock p, #UserList .AddUserBlock p,

View file

@ -1868,7 +1868,7 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important;
background-color: #343434; background-color: #343434;
} }
.AddUserErrors, .update-user-fail, .EditUserErrors, .update-password-fail { .AddUserErrors, .update-user-fail, .EditUserErrors, .update-password-fail, .icon-red-error {
background-color: #f22;; background-color: #f22;;
color: #ffd5dc; color: #ffd5dc;
border-left:solid 3px #f22; border-left:solid 3px #f22;
@ -1903,7 +1903,8 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important;
.update-user-success, .update-user-success,
.update-password-success, .update-password-success,
.update-username-success { .update-username-success,
.border-green {
border-left: 2px solid #a9f6e3; border-left: 2px solid #a9f6e3;
} }

View file

@ -1041,6 +1041,43 @@ function pwg_generate_reset_password_mail($username, $reset_password_link, $gall
); );
} }
/**
* Generate content mail for set password
*
* Return the content mail to send
* @since 15
* @param string $username
* @param string $reset_password_link
* @param string $gallery_title
* @return string mail content
*/
function pwg_generate_set_password_mail($username, $set_password_link, $gallery_title)
{
set_make_full_url();
$message = l10n('Someone requested that the password be set for the following user account:') . "\r\n\r\n";
$message.= l10n(
'Username "%s" on gallery %s',
$username,
get_gallery_home_url()
);
$message.= "\r\n\r\n";
$message.= l10n('To set your password, visit the following address:') . "\r\n";
$message.= $set_password_link;
$message.= "\r\n\r\n";
$message.= l10n('If this was a mistake, just ignore this email and nothing will happen.')."\r\n";
unset_make_full_url();
$message = trigger_change('render_lost_password_mail_content', $message);
return array(
'subject' => l10n('Welcome to ') . '['.$gallery_title.']',
'content' => $message,
'email_format' => 'text/plain',
);
}
trigger_notify('functions_mail_included'); trigger_notify('functions_mail_included');
?> ?>

View file

@ -1905,4 +1905,26 @@ function userprefs_get_param($param, $default_value=null)
return $default_value; return $default_value;
} }
/**
* See if this is the first time the user has logged on
*
* @since 15
* @param int $user_id
* @return bool true if first connexion else false
*/
function first_connexion($user_id)
{
$query = '
SELECT COUNT(*)
FROM '.ACTIVITY_TABLE.'
WHERE action = \'login\' and performed_by = '.$user_id.'';
list($logged_in) = pwg_db_fetch_row(pwg_query($query));
if ($logged_in > 0)
{
return false;
}
return true;
}
?> ?>

View file

@ -392,13 +392,18 @@ function ws_users_add($params, &$service)
} }
} }
if ($params['auto_password'])
{
$params['password'] = generate_key(rand(15, 20));
}
$user_id = register_user( $user_id = register_user(
$params['username'], $params['username'],
$params['password'], $params['password'],
$params['email'], $params['email'],
false, // notify admin false, // notify admin
$errors, $errors,
$params['send_password_by_mail'] false // $params['send_password_by_mail']
); );
if (!$user_id) if (!$user_id)
@ -1006,7 +1011,15 @@ function ws_users_generate_reset_password_link($params, &$service)
if ($params['send_by_mail'] and !empty($user_lost['email'])) if ($params['send_by_mail'] and !empty($user_lost['email']))
{ {
$email_params = pwg_generate_reset_password_mail($user_lost['username'], $generate_link['reset_password_link'], $conf['gallery_title']); $first_login = first_connexion($params['user_id']);
if ($first_login)
{
$email_params = pwg_generate_set_password_mail($user_lost['username'], $generate_link['reset_password_link'], $conf['gallery_title']);
}
else
{
$email_params = pwg_generate_reset_password_mail($user_lost['username'], $generate_link['reset_password_link'], $conf['gallery_title']);
}
// Here we remove the display of errors because they prevent the response from being parsed // Here we remove the display of errors because they prevent the response from being parsed
if (@pwg_mail($user_lost['email'], $email_params)) if (@pwg_mail($user_lost['email'], $email_params))
{ {

View file

@ -224,12 +224,14 @@ if (isset($_GET['key']) and !is_a_guest())
if (isset($_GET['key']) and !isset($_POST['submit'])) if (isset($_GET['key']) and !isset($_POST['submit']))
{ {
$first_login = false;
$user_id = check_password_reset_key($_GET['key']); $user_id = check_password_reset_key($_GET['key']);
if (is_numeric($user_id)) if (is_numeric($user_id))
{ {
$userdata = getuserdata($user_id, false); $userdata = getuserdata($user_id, false);
$page['username'] = $userdata['username']; $page['username'] = $userdata['username'];
$template->assign('key', $_GET['key']); $template->assign('key', $_GET['key']);
$first_login = first_connexion($user_id);
if (!isset($page['action'])) if (!isset($page['action']))
{ {
@ -278,6 +280,10 @@ if ('lost' == $page['action'])
$template->assign('username_or_email', htmlspecialchars(stripslashes($_POST['username_or_email']))); $template->assign('username_or_email', htmlspecialchars(stripslashes($_POST['username_or_email'])));
} }
} }
else if ('reset' == $page['action'] and isset($first_login) and $first_login)
{
$title = l10n('Welcome');
}
$page['body_id'] = 'thePasswordPage'; $page['body_id'] = 'thePasswordPage';

5
ws.php
View file

@ -1155,6 +1155,11 @@ enabled_high, registration_date, registration_date_string, registration_date_sin
'ws_users_add', 'ws_users_add',
array( array(
'username' => array(), 'username' => array(),
'auto_password' => array(
'default'=>false,
'flags'=>WS_TYPE_BOOL,
'info' => 'if true ignores password and confirm password'
),
'password' => array('default'=>null), 'password' => array('default'=>null),
'password_confirm' => array('flags'=>WS_PARAM_OPTIONAL), 'password_confirm' => array('flags'=>WS_PARAM_OPTIONAL),
'email' => array('default'=>null), 'email' => array('default'=>null),