ShareLinks: resolve movie id from home cards and tighten guest lockdown
Creating a link from a home-page carousel resolved the wrong id: the card context menu detaches into a body-level action sheet, so the DOM walk missed the movie and fell back to the first data-id on the page (a library folder), which then got rejected. Capture the pointed-at card's item id at pointerdown so the action injects the right id. Guest lockdown let guests reach the home page: nav was hidden by matching English label keywords, which never matched the French UI, and any details/list route counted as allowed. Hide the header back/home/drawer/search buttons by CSS class instead, and treat only the guest's own item page (or a playback route) as allowed so off-item routes redirect back to the shared title.
Cette révision appartient à :
@@ -2,7 +2,7 @@
|
|||||||
var pluginId = '68540b76-ee74-436d-85ff-2abc884bbea6';
|
var pluginId = '68540b76-ee74-436d-85ff-2abc884bbea6';
|
||||||
var copyLabel = 'Copy Stream URL';
|
var copyLabel = 'Copy Stream URL';
|
||||||
var actionLabel = 'Create guest link';
|
var actionLabel = 'Create guest link';
|
||||||
var clientVersion = '1.0.0-ui-modal-6';
|
var clientVersion = '1.0.0-ui-modal-7';
|
||||||
var allowedItemStorageKey = 'sharelinks.allowedItemId';
|
var allowedItemStorageKey = 'sharelinks.allowedItemId';
|
||||||
var guestClassName = 'sharelinks-guest';
|
var guestClassName = 'sharelinks-guest';
|
||||||
var hiddenAttr = 'data-sharelinks-hidden';
|
var hiddenAttr = 'data-sharelinks-hidden';
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
var scanQueued = false;
|
var scanQueued = false;
|
||||||
var bootRetry = null;
|
var bootRetry = null;
|
||||||
var observer = null;
|
var observer = null;
|
||||||
|
var lastContextItemId = null;
|
||||||
|
var lastContextItemTs = 0;
|
||||||
var historyPatched = false;
|
var historyPatched = false;
|
||||||
var durationOptions = [
|
var durationOptions = [
|
||||||
{ label: '1 hour', hours: 1 },
|
{ label: '1 hour', hours: 1 },
|
||||||
@@ -62,6 +64,19 @@
|
|||||||
window.addEventListener('hashchange', scheduleWork, true);
|
window.addEventListener('hashchange', scheduleWork, true);
|
||||||
window.addEventListener('popstate', scheduleWork, true);
|
window.addEventListener('popstate', scheduleWork, true);
|
||||||
|
|
||||||
|
document.addEventListener('pointerdown', function (event) {
|
||||||
|
var node = event.target;
|
||||||
|
while (node && node !== document) {
|
||||||
|
var id = readItemIdFromNode(node);
|
||||||
|
if (id) {
|
||||||
|
lastContextItemId = id;
|
||||||
|
lastContextItemTs = Date.now();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node = node.parentElement;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
observer = new MutationObserver(scheduleWork);
|
observer = new MutationObserver(scheduleWork);
|
||||||
observer.observe(document.body, { childList: true, subtree: true });
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
|
||||||
@@ -162,7 +177,7 @@
|
|||||||
// UX-only lockdown: the guest user's real access boundary is still the
|
// UX-only lockdown: the guest user's real access boundary is still the
|
||||||
// server-side policy and item tags. This just keeps the web client out
|
// server-side policy and item tags. This just keeps the web client out
|
||||||
// of the user's way.
|
// of the user's way.
|
||||||
if (context.allowedItemId && !isAllowedLocation()) {
|
if (context.allowedItemId && !isAllowedLocation(context.allowedItemId)) {
|
||||||
navigateToItem(context.allowedItemId);
|
navigateToItem(context.allowedItemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,7 +226,11 @@
|
|||||||
|
|
||||||
var style = document.createElement('style');
|
var style = document.createElement('style');
|
||||||
style.id = 'ShareLinksGuestStyle';
|
style.id = 'ShareLinksGuestStyle';
|
||||||
style.textContent = 'body.' + guestClassName + ' [' + hiddenAttr + '="1"] { display: none !important; }';
|
style.textContent = 'body.' + guestClassName + ' [' + hiddenAttr + '="1"],'
|
||||||
|
+ ' body.' + guestClassName + ' .headerBackButton,'
|
||||||
|
+ ' body.' + guestClassName + ' .headerHomeButton,'
|
||||||
|
+ ' body.' + guestClassName + ' .mainDrawerButton,'
|
||||||
|
+ ' body.' + guestClassName + ' .headerSearchButton { display: none !important; }';
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,6 +444,10 @@
|
|||||||
current = current.parentElement;
|
current = current.parentElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastContextItemId && (Date.now() - lastContextItemTs) < 8000) {
|
||||||
|
return lastContextItemId;
|
||||||
|
}
|
||||||
|
|
||||||
return findItemIdInDocument();
|
return findItemIdInDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,8 +528,16 @@
|
|||||||
return /#\/(?:details|video|playback|list|item)/i.test(location.hash || '');
|
return /#\/(?:details|video|playback|list|item)/i.test(location.hash || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAllowedLocation() {
|
function isAllowedLocation(allowedItemId) {
|
||||||
return isDetailsOrPlaybackRoute();
|
var hash = location.hash || '';
|
||||||
|
if (/#\/(?:video|playback)/i.test(hash)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (/#\/(?:details|item)/i.test(hash)) {
|
||||||
|
var id = parseItemIdFromUrl();
|
||||||
|
return !!id && !!allowedItemId && id.toLowerCase() === String(allowedItemId).toLowerCase();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigateToItem(itemId) {
|
function navigateToItem(itemId) {
|
||||||
|
|||||||
Référencer dans un nouveau ticket
Bloquer un utilisateur