Merge branch 'staging' into roster

This commit is contained in:
yflory 2024-08-29 16:47:55 +02:00
commit f31ebfe7ec
15 changed files with 141 additions and 37 deletions

View File

@ -136,8 +136,9 @@ define(req, function(AppConfig, Default, Language) {
}
};
Messages.team_autoTrim = "Removing unused history... Please wait."; // XXX
Messages.admin_mfa_confirm_enable = "Are you sure you want to enable Multi-Factor Authentication?"; // XXX
Messages.admin_mfa_confirm_disable = "Are you sure you want to disable Multi-Factor Authentication?"; // XXX
return Messages;

View File

@ -953,6 +953,9 @@
li, li .fa, li .cptools {
cursor: pointer;
border-radius: @variables_radius;
&:focus {
outline: @cryptpad_color_brand solid 2px;
}
}
&> p {
display: flex;

View File

@ -33,8 +33,8 @@
color: @cp_drive-fg;
}
&.cp-icons-element-selected {
background: @cp_drive-icon-hover;
color: @cp_drive-fg;
outline: @cryptpad_color_brand solid 2px;
}
.fa, .cptools {
display: block;

View File

@ -28,6 +28,37 @@
max-height: 250px;
}
}
#cp-sidebarlayout-container {
#cp-sidebarlayout-rightside {
.cp-sidebarlayout-element[data-item] {
div#cp-admin-table-container {
overflow-x: auto;
.cp-sidebar-table#cp-admin-table {
tr {
display: flex;
}
th, td {
flex: 1;
word-wrap: break-word;
white-space: normal;
min-width: 13rem;
margin-right: 0px;
}
@media (max-width: @browser_media-not-small) {
width: 100%;
tr {
width: 100%;
}
th, td {
margin-right: 0;
min-width: 7rem;
}
}
}
}
}
}
}
.cp-admin-color-current {
width: 20px;
height: 20px;

View File

@ -578,23 +578,38 @@ define([
return APP.instanceStatus.enforceMFA;
},
query: function (val, setState) {
sFrameChan.query('Q_ADMIN_RPC', {
cmd: 'ADMIN_DECREE',
data: ['ENFORCE_MFA', [val]]
}, function (e, response) {
if (e || response.error) {
UI.warn(Messages.error);
console.error(e, response);
}
APP.updateStatus(function () {
setState(APP.instanceStatus.enforceMFA);
flushCache();
var isChecked = APP.instanceStatus.enforceMFA;
function showConfirmation(isChecked, setState) {
const confirmationContent = isChecked ? Messages.admin_mfa_confirm_disable : Messages.admin_mfa_confirm_enable;
UI.confirm(confirmationContent, function (confirmed) {
if (!confirmed) {
// User canceled their changes, restore the checkbox value
setState(isChecked);
return;
}
// User confirmed their changes, call the command and update the state
sFrameChan.query('Q_ADMIN_RPC', {
cmd: 'ADMIN_DECREE',
data: ['ENFORCE_MFA', [val]]
}, function (e, response) {
if (e || response.error) {
UI.warn(Messages.error);
console.error(e, response);
} else {
APP.updateStatus(function () {
setState(APP.instanceStatus.enforceMFA);
flushCache();
});
}
});
});
});
},
}
showConfirmation(isChecked, setState);
}
});
var getInstanceString = function (attr) {
var val = APP.instanceStatus[attr];
var type = typeof(val);
@ -1101,6 +1116,9 @@ define([
""
];
var list = blocks.table(header, []);
list.setAttribute('id', 'cp-admin-table');
let div = blocks.block([list]);
div.setAttribute('id', 'cp-admin-table-container');
var nav = blocks.nav([button, refreshButton]);
var form = blocks.form([
@ -1201,7 +1219,7 @@ define([
});
});
cb([form, list]);
cb([form, div]);
});
var getBlockId = (val) => {
@ -1413,6 +1431,9 @@ define([
""
];
var list = blocks.table(header, []);
list.setAttribute('id', 'cp-admin-table');
let div = blocks.block([list]);
div.setAttribute('id', 'cp-admin-table-container');
var nav = blocks.nav([button, refreshButton]);
@ -1581,7 +1602,7 @@ define([
});
});
cb([form, list]);
cb([form, div]);
});
// Msg.admin_defaultlimitHint, .admin_defaultlimitTitle
@ -1741,6 +1762,9 @@ define([
Messages.admin_note
];
var table = blocks.table(header, []);
table.setAttribute('id', 'cp-admin-table');
let div = blocks.block([table]);
div.setAttribute('id', 'cp-admin-table-container');
let $table = $(table).hide();
APP.refreshLimits = function () {
@ -1798,7 +1822,7 @@ define([
});
};
APP.refreshLimits();
cb(table);
cb(div);
});
// Msg.admin_accountMetadataHint.admin_accountMetadataTitle
@ -3594,6 +3618,9 @@ define([
];
var table = blocks.table(header, []);
table.setAttribute('id', 'cp-admin-table');
let div = blocks.block([table]);
div.setAttribute('id', 'cp-admin-table-container');
const onRefresh = function () {
sFrameChan.query('Q_ADMIN_RPC', {
@ -3626,7 +3653,7 @@ define([
onRefresh();
onRefreshPerformance.reg(onRefresh);
cb(table);
cb(div);
});

View File

@ -157,6 +157,11 @@
border-radius: @variables_radius_L;
}
.tui-full-calendar-popup-container {
.tui-full-calendar-section-allday{
&:focus {
outline: @cryptpad_color_brand solid 2px;
}
}
min-width: 100%;
background: @cp_flatpickr-bg;
color: @cryptpad_text_col;
@ -208,6 +213,9 @@
text-overflow: ellipsis;
font: @colortheme_app-font;
padding: 0 10px;
&:focus{
outline: @cryptpad_color_brand solid 2px;
}
}
input { flex: 1; }
}
@ -403,6 +411,11 @@
& > input {
height: 40px;
}
.tui-full-calendar-content{
&:focus{
outline: @cryptpad_color_brand solid 2px;
}
}
}
// margin-bottom: 20px;
input {

View File

@ -2063,6 +2063,15 @@ APP.recurrenceRule = {
editor.setOption('readOnly', false);
editor.setOption('autoRefresh', true);
editor.setOption('gutters', []);
editor.on('keydown', function (editor, e) {
if (e.which === 27) {
let $next = $(e.target).closest('.tui-full-calendar-popup-section').next();
if ($next.length) {
$next.find('#tui-full-calendar-schedule-start-date').focus();
}
e.stopPropagation();
}
});
cm.configureTheme(common, function () {});
editor.setValue(oldEventBody);
@ -2147,6 +2156,13 @@ APP.recurrenceRule = {
$el.find('input').attr('autocomplete', 'off');
$el.find('.tui-full-calendar-dropdown-button').addClass('btn btn-secondary');
$el.find('.tui-full-calendar-popup-close').addClass('btn btn-cancel fa fa-times cp-calendar-close').empty();
$el.find('.tui-full-calendar-section-allday').attr('tabindex', 0);
$el.find('.cp-calendar-close').attr('tabindex',-1);
$el.find('.tui-full-calendar-section-allday').keydown(function (e) {
if (e.which === 13) {
$(this).click();
}
});
var $container = $el.closest('.tui-full-calendar-floating-layer');
$container.addClass('cp-calendar-popup-flex');
@ -2209,6 +2225,7 @@ APP.recurrenceRule = {
setFormat(allDay);
});
});
UI.addTabListener(el);
};
var onCalendarEditPopup = function (el) {
var $el = $(el);
@ -2244,6 +2261,7 @@ APP.recurrenceRule = {
var data = ev.schedule || {};
var id = data.id;
UI.addTabListener(el);
if (!id) { return; }
if (id.indexOf('|') === -1) { return; } // Original event ID doesn't contain |

View File

@ -164,12 +164,12 @@ define([
dialog.okButton = function (content, classString) {
var sel = typeof(classString) === 'string'? 'button.ok.' + classString:'button.btn.ok.primary';
return h(sel, { tabindex: '2', }, content || Messages.okButton);
return h(sel, content || Messages.okButton);
};
dialog.cancelButton = function (content, classString) {
var sel = typeof(classString) === 'string'? 'button.' + classString:'button.btn.cancel';
return h(sel, { tabindex: '1'}, content || Messages.cancelButton);
return h(sel, content || Messages.cancelButton);
};
dialog.message = function (text) {
@ -577,7 +577,7 @@ define([
return frame;
};
let addTabListener = frame => {
let addTabListener = UI.addTabListener = frame => {
// find focusable elements
let modalElements = $(frame).find('a, button, input, [tabindex]:not([tabindex="-1"]), textarea').filter(':visible').filter(':not(:disabled)');
@ -670,6 +670,7 @@ define([
$modal: $blockContainer,
show: function () {
$blockContainer.css('display', 'flex');
addTabListener($blockContainer);
},
hide: hide
};
@ -719,6 +720,7 @@ define([
Notifier.notify();
});
addTabListener(frame);
return {
element: frame,
delete: close
@ -770,7 +772,7 @@ define([
document.body.appendChild(frame);
setTimeout(function () {
$(input).select().focus();
addTabListener(frame);
Notifier.notify();
});
};

View File

@ -3559,7 +3559,7 @@ define([
$(link).click(function (e) {
e.preventDefault();
e.stopPropagation();
var obj = { pw: msg.content.password || '' };
var obj = { pw: msg.content.password || '', f: 1 };
common.openURL(Hash.getNewPadURL(msg.content.href, obj));
});
@ -3615,7 +3615,7 @@ define([
// Add the pad to your drive
// This command will also add your mailbox to the metadata log
// The callback is called when the pad is stored, independantly of the metadata command
// The callback is called when the pad is stored, independently of the metadata command
if (data.calendar) {
var calendarModule = common.makeUniversal('calendar');
var calendarData = data.calendar;

View File

@ -2619,7 +2619,8 @@ define([
disableCache: localStorage['CRYPTPAD_STORE|disableCache'],
driveEvents: !rdyCfg.noDrive, //rdyCfg.driveEvents // Boolean
lastVisit: Number(localStorage.lastVisit) || undefined,
blockId: blockId
blockId: blockId,
blockHash: blockHash
};
common.userHash = userHash || LocalStore.getUserHash();

View File

@ -129,6 +129,7 @@ define([
var obj = {
p: msg.content.isTemplate ? ['template'] : undefined,
t: teamNotification || undefined,
f: 1,
pw: msg.content.password || ''
};
common.openURL(Hash.getNewPadURL(msg.content.href, obj));

View File

@ -8,7 +8,8 @@ define([
'/common/common-hash.js',
'/common/common-util.js',
'/components/chainpad-crypto/crypto.js',
], function (ApiConfig, Messaging, Hash, Util, Crypto) {
'/common/outer/login-block.js',
], function (ApiConfig, Messaging, Hash, Util, Crypto, Block) {
// Random timeout between 10 and 30 times your sync time (lag + chainpad sync)
var getRandomTimeout = function (ctx) {
@ -237,6 +238,14 @@ define([
cb(true);
};
// Encrypt the password under the right key before sending it via URL hash
var encryptPassword = function(ctx, password) {
let uHash = ctx.store.data.blockHash;
let uSecret = Block.parseBlockHash(uHash);
let key = uSecret.keys.symmetric;
return Crypto.encrypt(password, key);
};
// Hide duplicates when receiving a SHARE_PAD notification:
// Keep only one notification per channel: the stronger and more recent one
var channels = {};
@ -265,8 +274,7 @@ define([
}
if (content.password) {
var key = ctx.store.driveSecret.keys.cryptKey;
content.password = Crypto.encrypt(content.password, key);
content.password = encryptPassword(ctx, content.password);
}
// Update the data
@ -384,8 +392,8 @@ define([
var channel = content.channel || content.teamChannel;
if (content.password) {
var key = ctx.store.driveSecret.keys.cryptKey;
content.password = Crypto.encrypt(content.password, key);
content.pw = content.password;
content.password = encryptPassword(ctx, content.password);
}
if (addOwners[channel]) { return void cb(true); }

View File

@ -1083,7 +1083,7 @@ define([
Cryptpad.addSharedFolder(null, secret, cb);
} else {
var _data = {
password: data.password,
password: data.pw || data.password,
href: data.href,
channel: data.channel,
title: data.title,
@ -1359,7 +1359,7 @@ define([
var viewH = Utils.Hash.getViewHashFromKeys(_secret);
var href = Utils.Hash.hashToHref(editH, parsed.type);
var roHref = Utils.Hash.hashToHref(viewH, parsed.type);
Cryptpad.setPadAttribute('password', password, w(), parsed.getUrl());
Cryptpad.setPadAttribute('password', pw, w(), parsed.getUrl());
Cryptpad.setPadAttribute('channel', chan, w(), parsed.getUrl());
Cryptpad.setPadAttribute('href', href, w(), parsed.getUrl());
Cryptpad.setPadAttribute('roHref', roHref, w(), parsed.getUrl());

View File

@ -1011,7 +1011,6 @@
min-width: 300px;
width: 300px;
position: absolute;
left: 20px;
word-break: break-word;
background: @cp_form-bg1;
z-index: 2;

View File

@ -516,7 +516,7 @@ define([
created++;
}
if (team.empty) {
var createTeamDiv = h('div.cp-team-list-team.empty'+createCls,{
var createTeamDiv = h('li.cp-team-list-team.empty'+createCls,{
tabindex: '0'
}, [
h('span.cp-team-list-name.empty', Messages.team_listSlot),
@ -533,7 +533,7 @@ define([
return;
}
var avatar = h('span.cp-avatar');
var teamDiv = h('div.cp-team-list-team',{
var teamDiv = h('li.cp-team-list-team',{
tabindex: '0'
}, [
h('span.cp-team-list-avatar', avatar),
@ -553,7 +553,7 @@ define([
}
});
});
content.push(h('div.cp-team-list-container', list));
content.push(h('ul.cp-team-list-container', list));
cb(content);
});
return content;