mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-03-28 17:42:57 +01:00
issue #2355 enforce ui context for API key management
...and improve profile JS. Replaces can_manage_api_key() with connected_with_pwg_ui() to ensure API key management is only allowed from UI logins, and sets 'connected_with' in session during auto-login. Refactors profile.js to respect canUpdatePreferences and canUpdatePassword, moves user state initialization to template, and improves preference reset/default logic. Also adjusts script loading and minor UI details in profile.tpl.
This commit is contained in:
@@ -1127,6 +1127,12 @@ function auto_login()
|
||||
$key = calculate_auto_login_key( $cookie[0], $cookie[1], $username );
|
||||
if ($key!==false and $key===$cookie[2])
|
||||
{
|
||||
// Since Piwigo 16, 'connected_with' in the session defines the authentication context (UI, API, etc).
|
||||
// Auto-login via remember-me may miss this, so we set it to 'pwg_ui' for UI logins (not API).
|
||||
if (script_basename() != 'ws')
|
||||
{
|
||||
$_SESSION['connected_with'] = 'pwg_ui';
|
||||
}
|
||||
log_user($cookie[0], true);
|
||||
trigger_notify('login_success', stripslashes($username));
|
||||
return true;
|
||||
@@ -2633,4 +2639,20 @@ SELECT
|
||||
|
||||
return $api_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is connected with pwg_ui (identification.php)
|
||||
*
|
||||
* @since 16
|
||||
* @return bool
|
||||
*/
|
||||
function connected_with_pwg_ui()
|
||||
{
|
||||
// You can manage your api key only if you are connected via identification.php
|
||||
if (isset($_SESSION['connected_with']) and 'pwg_ui' === $_SESSION['connected_with'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -962,7 +962,7 @@ function ws_create_api_key($params, &$service)
|
||||
{
|
||||
global $user, $logger;
|
||||
|
||||
if (is_a_guest() OR !can_manage_api_key()) return new PwgError(401, 'Acces Denied');
|
||||
if (is_a_guest() OR !connected_with_pwg_ui()) return new PwgError(401, 'Acces Denied');
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
@@ -999,7 +999,7 @@ function ws_revoke_api_key($params, &$service)
|
||||
{
|
||||
global $user, $logger;
|
||||
|
||||
if (is_a_guest() OR !can_manage_api_key()) return new PwgError(401, 'Acces Denied');
|
||||
if (is_a_guest() OR !connected_with_pwg_ui()) return new PwgError(401, 'Acces Denied');
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
@@ -1038,7 +1038,7 @@ function ws_edit_api_key($params, &$service)
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
|
||||
if (!can_manage_api_key())
|
||||
if (!connected_with_pwg_ui())
|
||||
{
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
@@ -1081,7 +1081,7 @@ function ws_get_api_key($params, &$service)
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
|
||||
if (!can_manage_api_key())
|
||||
if (!connected_with_pwg_ui())
|
||||
{
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
@@ -1095,14 +1095,4 @@ function ws_get_api_key($params, &$service)
|
||||
|
||||
return $api_keys ?? l10n('No API key found');
|
||||
}
|
||||
|
||||
function can_manage_api_key()
|
||||
{
|
||||
// You can manage your api key only if you are connected via identification.php
|
||||
if (isset($_SESSION['connected_with']) and 'pwg_ui' === $_SESSION['connected_with'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -21,7 +21,9 @@ $(function() {
|
||||
}
|
||||
});
|
||||
|
||||
$('#account-section .display-btn').trigger('click');
|
||||
setTimeout(() => {
|
||||
$('#account-section .display-btn').trigger('click');
|
||||
}, 100);
|
||||
|
||||
$('#save_account').on('click', function() {
|
||||
const mail = $('#email').val();
|
||||
@@ -32,48 +34,71 @@ $(function() {
|
||||
setInfos({ email: mail });
|
||||
});
|
||||
|
||||
$('#save_preferences').on('click', function() {
|
||||
const values = {
|
||||
nb_image_page: $('#nb_image_page').val(),
|
||||
theme: $('select[name="theme"]').val(),
|
||||
language: $('select[name="language"]').val(),
|
||||
recent_period: $('#recent_period').val(),
|
||||
expand: $('#opt_album').is(':checked'),
|
||||
show_nb_comments: $('#opt_comment').is(':checked'),
|
||||
show_nb_hits: $('#opt_hits').is(':checked')
|
||||
}
|
||||
if (canUpdatePreferences) {
|
||||
$('#save_preferences').on('click', function () {
|
||||
const values = {
|
||||
nb_image_page: $('#nb_image_page').val(),
|
||||
theme: $('select[name="theme"]').val(),
|
||||
language: $('select[name="language"]').val(),
|
||||
recent_period: $('#recent_period').val(),
|
||||
expand: $('#opt_album').is(':checked'),
|
||||
show_nb_comments: $('#opt_comment').is(':checked'),
|
||||
show_nb_hits: $('#opt_hits').is(':checked')
|
||||
}
|
||||
|
||||
if (values.nb_image_page == '') {
|
||||
$('#error_nb_image').show();
|
||||
return;
|
||||
}
|
||||
if (values.nb_image_page == '') {
|
||||
$('#error_nb_image').show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (values.recent_period == '') {
|
||||
$('#error_period').show();
|
||||
return;
|
||||
}
|
||||
if (values.recent_period == '') {
|
||||
$('#error_period').show();
|
||||
return;
|
||||
}
|
||||
|
||||
setInfos({...values});
|
||||
});
|
||||
setInfos({ ...values });
|
||||
});
|
||||
|
||||
$('#save_password').on('click', function() {
|
||||
const passwords = {
|
||||
password: $('#password').val(),
|
||||
new_password: $('#password_new').val(),
|
||||
conf_new_password: $('#password_conf').val(),
|
||||
}
|
||||
if (passwords.password == '' || passwords.new_password == '' || passwords.conf_new_password == '') {
|
||||
$('#password-section input').each((i, element) => {
|
||||
const el = $(element);
|
||||
if (el.val() == '') {
|
||||
el.parent().siblings().show();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
setInfos({...passwords});
|
||||
$('#password-section input').val('');
|
||||
});
|
||||
$('#reset_preferences').on('click', function () {
|
||||
$('input[name="nb_image_page"]').val(user.nb_image_page);
|
||||
$('select[name="theme"]').val(user.theme);
|
||||
$('select[name="language"]').val(user.language);
|
||||
$('input[name="recent_period"]').val(user.recent_period);
|
||||
$('#opt_album').prop('checked', user.opt_album);
|
||||
$('#opt_comment').prop('checked', user.opt_comment);
|
||||
$('#opt_hits').prop('checked', user.opt_hits);
|
||||
});
|
||||
|
||||
$('#default_preferences').on('click', function () {
|
||||
$('input[name="nb_image_page"]').val(preferencesDefaultValues.nb_image_page);
|
||||
$('input[name="recent_period"]').val(preferencesDefaultValues.recent_period);
|
||||
$('#opt_album').prop('checked', preferencesDefaultValues.opt_album);
|
||||
$('#opt_comment').prop('checked', preferencesDefaultValues.opt_comment);
|
||||
$('#opt_hits').prop('checked', preferencesDefaultValues.opt_hits);
|
||||
});
|
||||
}
|
||||
|
||||
if (canUpdatePassword) {
|
||||
$('#save_password').on('click', function () {
|
||||
const passwords = {
|
||||
password: $('#password').val(),
|
||||
new_password: $('#password_new').val(),
|
||||
conf_new_password: $('#password_conf').val(),
|
||||
}
|
||||
if (passwords.password == '' || passwords.new_password == '' || passwords.conf_new_password == '') {
|
||||
$('#password-section input').each((i, element) => {
|
||||
const el = $(element);
|
||||
if (el.val() == '') {
|
||||
el.parent().siblings().show();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
setInfos({ ...passwords });
|
||||
$('#password-section input').val('');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
standardSaveSelector.forEach((selector, i) => {
|
||||
$(selector).on('click', function() {
|
||||
@@ -88,35 +113,6 @@ $(function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const userDefaultValues = {
|
||||
nb_image_page: $('input[name="nb_image_page"]').val(),
|
||||
theme: $('select[name="theme"]').val(),
|
||||
language: $('select[name="language"]').val(),
|
||||
recent_period: $('input[name="recent_period"]').val(),
|
||||
opt_album: $('#opt_album').is(':checked'),
|
||||
opt_comment: $('#opt_comment').is(':checked'),
|
||||
opt_hits: $('#opt_hits').is(':checked'),
|
||||
}
|
||||
|
||||
$('#reset_preferences').on('click', function() {
|
||||
$('input[name="nb_image_page"]').val(userDefaultValues.nb_image_page);
|
||||
$('select[name="theme"]').val(userDefaultValues.theme);
|
||||
$('select[name="language"]').val(userDefaultValues.language);
|
||||
$('input[name="recent_period"]').val(userDefaultValues.recent_period);
|
||||
$('#opt_album').prop('checked', userDefaultValues.opt_album);
|
||||
$('#opt_comment').prop('checked', userDefaultValues.opt_comment);
|
||||
$('#opt_hits').prop('checked', userDefaultValues.opt_hits);
|
||||
});
|
||||
|
||||
$('#default_preferences').on('click', function() {
|
||||
$('input[name="nb_image_page"]').val(preferencesDefaultValues.nb_image_page);
|
||||
$('input[name="recent_period"]').val(preferencesDefaultValues.recent_period);
|
||||
$('#opt_album').prop('checked', preferencesDefaultValues.opt_album);
|
||||
$('#opt_comment').prop('checked', preferencesDefaultValues.opt_comment);
|
||||
$('#opt_hits').prop('checked', preferencesDefaultValues.opt_hits);
|
||||
});
|
||||
|
||||
// API KEY BELOW
|
||||
if (!can_manage_api) {
|
||||
$('.can-manage').hide();
|
||||
@@ -202,24 +198,26 @@ function setInfos(params, method='pwg.users.setMyInfo', callback=null, errCallba
|
||||
data: all_params,
|
||||
success: (data) => {
|
||||
if (data.stat == 'ok') {
|
||||
user = {...user, ...params};
|
||||
if (typeof callback === 'function') {
|
||||
callback(data.result);
|
||||
return;
|
||||
};
|
||||
pwgToaster({ text: data.result, icon: 'success' });
|
||||
return;
|
||||
} else if (data.stat == 'fail') {
|
||||
pwgToaster({ text: data.message, icon: 'error' });
|
||||
} else {
|
||||
pwgToaster({ text: str_handle_error, icon: 'error' });
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
if (typeof errCallback === 'function') {
|
||||
errCallback(data);
|
||||
return;
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
pwgToaster({ text: e.responseJSON?.message ?? str_handle_error, icon: 'error' });
|
||||
if (typeof callback === 'function') {
|
||||
if (typeof errCallback === 'function') {
|
||||
errCallback(e);
|
||||
return;
|
||||
}
|
||||
@@ -237,7 +235,7 @@ function getAllApiKeys(reset = false) {
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.stat == 'ok') {
|
||||
if (typeof res.result === 'string') {
|
||||
if (typeof res.result === 'string' || res.result === false) {
|
||||
// No keys
|
||||
} else {
|
||||
AddApiLine(res.result, reset);
|
||||
|
||||
@@ -8,9 +8,23 @@ var selected_language = `{$language_options[$current_language]}`;
|
||||
var url_logo_dark = `{$ROOT_URL}themes/standard_pages/images/piwigo_logo_dark.svg`;
|
||||
</script>
|
||||
{combine_script id='standard_pages_js' load='async' require='jquery' path='themes/standard_pages/js/standard_pages.js'}
|
||||
{combine_script id='standard_profile_js' load='async' require='jquery' path='themes/standard_pages/js/profile.js'}
|
||||
{combine_script id='standard_profile_js' load='footer' require='jquery' path='themes/standard_pages/js/profile.js'}
|
||||
{combine_script id='common' load='footer' require='jquery' path='admin/themes/default/js/common.js'}
|
||||
{footer_script}
|
||||
let user = {
|
||||
username: "{$USERNAME}",
|
||||
email: "{$EMAIL}",
|
||||
nb_image_page: $('input[name="nb_image_page"]').val(),
|
||||
theme: $('select[name="theme"]').val(),
|
||||
language: $('select[name="language"]').val(),
|
||||
recent_period: $('input[name="recent_period"]').val(),
|
||||
opt_album: $('#opt_album').is(':checked'),
|
||||
opt_comment: $('#opt_comment').is(':checked'),
|
||||
opt_hits: $('#opt_hits').is(':checked')
|
||||
}
|
||||
|
||||
const canUpdatePreferences = {if $ALLOW_USER_CUSTOMIZATION}true{else}false{/if};
|
||||
const canUpdatePassword = {if not $SPECIAL_USER}true{else}false{/if};
|
||||
const standardSaveSelector = [];
|
||||
const preferencesDefaultValues = {
|
||||
nb_image_page: {$DEFAULT_USER_VALUES['nb_image_page']},
|
||||
@@ -36,6 +50,7 @@ const str_revoke_key = "{'Do you really want to revoke the "%s" API key?'|transl
|
||||
const str_api_revoked = "{"API Key has been successfully revoked."|translate|escape:javascript}";
|
||||
const str_api_edited = "{"API Key has been successfully edited."|translate|escape:javascript}";
|
||||
const no_time_elapsed = "{"right now"|translate|escape:javascript}";
|
||||
const str_must_not_empty = "{'must not be empty'|translate|escape:javascript}";
|
||||
{/footer_script}
|
||||
|
||||
<container id="mode" class="light">
|
||||
@@ -69,7 +84,7 @@ const no_time_elapsed = "{"right now"|translate|escape:javascript}";
|
||||
<label>{'Username'|translate}</label>
|
||||
<div class="row-flex input-container username">
|
||||
<i class="gallery-icon-user"></i>
|
||||
<p>{$USERNAME}</p>
|
||||
<p id="username">{$USERNAME}</p>
|
||||
<input id="pwg_token" type="hidden" value="{$PWG_TOKEN}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user