nodebb-plugin-pdf-secure 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/static/lib/main.js +57 -26
- package/static/viewer.html +6 -62
package/package.json
CHANGED
package/static/lib/main.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// Main plugin logic - PDF links become inline embedded viewers
|
|
3
|
+
// Main plugin logic - PDF links become inline embedded viewers with lazy loading
|
|
6
4
|
(async function () {
|
|
7
5
|
try {
|
|
8
6
|
var hooks = await app.require('hooks');
|
|
9
|
-
console.log('[PDF-Secure] Hooks loaded');
|
|
10
7
|
|
|
11
8
|
hooks.on('action:ajaxify.end', function () {
|
|
12
|
-
console.log('[PDF-Secure] ajaxify.end');
|
|
13
9
|
interceptPdfLinks();
|
|
14
10
|
});
|
|
15
11
|
} catch (err) {
|
|
@@ -29,14 +25,13 @@ console.log('[PDF-Secure] main.js loaded');
|
|
|
29
25
|
var href = link.getAttribute('href');
|
|
30
26
|
var parts = href.split('/');
|
|
31
27
|
var filename = parts[parts.length - 1];
|
|
32
|
-
console.log('[PDF-Secure] Embedding:', filename);
|
|
33
28
|
|
|
34
|
-
// Create
|
|
29
|
+
// Create container with loading placeholder
|
|
35
30
|
var container = document.createElement('div');
|
|
36
31
|
container.className = 'pdf-secure-embed';
|
|
37
32
|
container.style.cssText = 'margin:16px 0;border-radius:12px;overflow:hidden;background:#1f1f1f;border:1px solid rgba(255,255,255,0.1);box-shadow:0 4px 20px rgba(0,0,0,0.25);';
|
|
38
33
|
|
|
39
|
-
// Header
|
|
34
|
+
// Header
|
|
40
35
|
var header = document.createElement('div');
|
|
41
36
|
header.className = 'pdf-secure-embed-header';
|
|
42
37
|
header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:linear-gradient(135deg,#2d2d2d 0%,#252525 100%);border-bottom:1px solid rgba(255,255,255,0.08);';
|
|
@@ -45,7 +40,6 @@ console.log('[PDF-Secure] main.js loaded');
|
|
|
45
40
|
title.className = 'pdf-secure-embed-title';
|
|
46
41
|
title.style.cssText = 'display:flex;align-items:center;gap:10px;color:#fff;font-size:14px;font-weight:500;';
|
|
47
42
|
|
|
48
|
-
// PDF icon with INLINE SIZE
|
|
49
43
|
var icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
50
44
|
icon.setAttribute('viewBox', '0 0 24 24');
|
|
51
45
|
icon.style.cssText = 'width:20px;height:20px;min-width:20px;max-width:20px;fill:#e81224;flex-shrink:0;';
|
|
@@ -58,7 +52,7 @@ console.log('[PDF-Secure] main.js loaded');
|
|
|
58
52
|
title.appendChild(icon);
|
|
59
53
|
title.appendChild(nameSpan);
|
|
60
54
|
|
|
61
|
-
// Actions
|
|
55
|
+
// Actions
|
|
62
56
|
var actions = document.createElement('div');
|
|
63
57
|
actions.style.cssText = 'display:flex;gap:8px;';
|
|
64
58
|
|
|
@@ -78,35 +72,72 @@ console.log('[PDF-Secure] main.js loaded');
|
|
|
78
72
|
header.appendChild(actions);
|
|
79
73
|
container.appendChild(header);
|
|
80
74
|
|
|
81
|
-
//
|
|
75
|
+
// Body with loading placeholder
|
|
82
76
|
var iframeWrapper = document.createElement('div');
|
|
83
77
|
iframeWrapper.className = 'pdf-secure-embed-body';
|
|
84
78
|
iframeWrapper.style.cssText = 'position:relative;width:100%;height:600px;background:#525659;';
|
|
85
79
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
80
|
+
// Loading placeholder
|
|
81
|
+
var loadingPlaceholder = document.createElement('div');
|
|
82
|
+
loadingPlaceholder.className = 'pdf-loading-placeholder';
|
|
83
|
+
loadingPlaceholder.style.cssText = 'position:absolute;top:0;left:0;right:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#2d2d2d;color:#fff;gap:16px;';
|
|
84
|
+
loadingPlaceholder.innerHTML = `
|
|
85
|
+
<svg viewBox="0 0 24 24" style="width:48px;height:48px;fill:#0078d4;animation:spin 1s linear infinite;">
|
|
86
|
+
<path d="M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z"/>
|
|
87
|
+
</svg>
|
|
88
|
+
<div style="font-size:14px;color:#a0a0a0;">PDF Yükleniyor...</div>
|
|
89
|
+
<style>@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}</style>
|
|
90
|
+
`;
|
|
91
|
+
iframeWrapper.appendChild(loadingPlaceholder);
|
|
93
92
|
|
|
94
|
-
iframeWrapper.appendChild(iframe);
|
|
95
93
|
container.appendChild(iframeWrapper);
|
|
96
94
|
|
|
97
|
-
// Fullscreen
|
|
95
|
+
// Fullscreen handler
|
|
98
96
|
fullscreenBtn.addEventListener('click', function () {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
iframe.webkitRequestFullscreen();
|
|
103
|
-
} else if (iframe.msRequestFullscreen) {
|
|
104
|
-
iframe.msRequestFullscreen();
|
|
97
|
+
var iframe = iframeWrapper.querySelector('iframe');
|
|
98
|
+
if (iframe) {
|
|
99
|
+
if (iframe.requestFullscreen) iframe.requestFullscreen();
|
|
100
|
+
else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen();
|
|
105
101
|
}
|
|
106
102
|
});
|
|
107
103
|
|
|
108
104
|
link.replaceWith(container);
|
|
105
|
+
|
|
106
|
+
// LAZY LOADING with Intersection Observer
|
|
107
|
+
var observer = new IntersectionObserver(function (entries) {
|
|
108
|
+
entries.forEach(function (entry) {
|
|
109
|
+
if (entry.isIntersecting) {
|
|
110
|
+
// Load iframe only when visible
|
|
111
|
+
loadPdfIframe(iframeWrapper, filename, loadingPlaceholder);
|
|
112
|
+
observer.disconnect();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}, {
|
|
116
|
+
rootMargin: '200px', // Start loading 200px before visible
|
|
117
|
+
threshold: 0
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
observer.observe(container);
|
|
109
121
|
});
|
|
110
122
|
});
|
|
111
123
|
}
|
|
124
|
+
|
|
125
|
+
function loadPdfIframe(wrapper, filename, placeholder) {
|
|
126
|
+
var iframe = document.createElement('iframe');
|
|
127
|
+
iframe.className = 'pdf-secure-iframe';
|
|
128
|
+
iframe.style.cssText = 'width:100%;height:100%;border:none;display:block;opacity:0;transition:opacity 0.3s;';
|
|
129
|
+
iframe.src = config.relative_path + '/plugins/pdf-secure/viewer?file=' + encodeURIComponent(filename);
|
|
130
|
+
iframe.setAttribute('frameborder', '0');
|
|
131
|
+
iframe.setAttribute('allowfullscreen', 'true');
|
|
132
|
+
|
|
133
|
+
// When iframe loads, fade in and remove placeholder
|
|
134
|
+
iframe.onload = function () {
|
|
135
|
+
iframe.style.opacity = '1';
|
|
136
|
+
if (placeholder && placeholder.parentNode) {
|
|
137
|
+
placeholder.remove();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
wrapper.appendChild(iframe);
|
|
142
|
+
}
|
|
112
143
|
})();
|
package/static/viewer.html
CHANGED
|
@@ -3143,14 +3143,10 @@
|
|
|
3143
3143
|
}
|
|
3144
3144
|
}, true);
|
|
3145
3145
|
|
|
3146
|
-
// 2. Block context menu (right-click)
|
|
3146
|
+
// 2. Block context menu (right-click) - EVERYWHERE
|
|
3147
3147
|
document.addEventListener('contextmenu', function (e) {
|
|
3148
|
-
// Allow our custom context menu for annotations
|
|
3149
|
-
if (e.target.closest('.annotationLayer') || e.target.closest('.pdfViewer')) {
|
|
3150
|
-
// Keep custom context menu behavior
|
|
3151
|
-
return;
|
|
3152
|
-
}
|
|
3153
3148
|
e.preventDefault();
|
|
3149
|
+
e.stopPropagation();
|
|
3154
3150
|
return false;
|
|
3155
3151
|
}, true);
|
|
3156
3152
|
|
|
@@ -3172,41 +3168,14 @@
|
|
|
3172
3168
|
return false;
|
|
3173
3169
|
}, true);
|
|
3174
3170
|
|
|
3175
|
-
// 5.
|
|
3176
|
-
let devToolsOpen = false;
|
|
3177
|
-
const threshold = 160;
|
|
3178
|
-
|
|
3179
|
-
function checkDevTools() {
|
|
3180
|
-
const widthThreshold = window.outerWidth - window.innerWidth > threshold;
|
|
3181
|
-
const heightThreshold = window.outerHeight - window.innerHeight > threshold;
|
|
3182
|
-
|
|
3183
|
-
if (widthThreshold || heightThreshold) {
|
|
3184
|
-
if (!devToolsOpen) {
|
|
3185
|
-
devToolsOpen = true;
|
|
3186
|
-
console.log('[Security] DevTools detected');
|
|
3187
|
-
// Optional: blur content when devtools open
|
|
3188
|
-
document.body.classList.add('devtools-open');
|
|
3189
|
-
}
|
|
3190
|
-
} else {
|
|
3191
|
-
if (devToolsOpen) {
|
|
3192
|
-
devToolsOpen = false;
|
|
3193
|
-
document.body.classList.remove('devtools-open');
|
|
3194
|
-
}
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
|
|
3198
|
-
// Check periodically
|
|
3199
|
-
setInterval(checkDevTools, 1000);
|
|
3200
|
-
window.addEventListener('resize', checkDevTools);
|
|
3201
|
-
|
|
3202
|
-
// 6. Block Print via window.print override
|
|
3171
|
+
// 5. Block Print via window.print override
|
|
3203
3172
|
window.print = function () {
|
|
3204
3173
|
console.log('[Security] Print function blocked');
|
|
3205
3174
|
alert('Yazdırma bu belgede engellenmiştir.');
|
|
3206
3175
|
return false;
|
|
3207
3176
|
};
|
|
3208
3177
|
|
|
3209
|
-
//
|
|
3178
|
+
// 6. Disable beforeprint event
|
|
3210
3179
|
window.addEventListener('beforeprint', function (e) {
|
|
3211
3180
|
e.preventDefault();
|
|
3212
3181
|
document.body.style.display = 'none';
|
|
@@ -3216,7 +3185,7 @@
|
|
|
3216
3185
|
document.body.style.display = '';
|
|
3217
3186
|
});
|
|
3218
3187
|
|
|
3219
|
-
//
|
|
3188
|
+
// 7. Block screenshot keyboard shortcuts
|
|
3220
3189
|
document.addEventListener('keyup', function (e) {
|
|
3221
3190
|
// PrintScreen key
|
|
3222
3191
|
if (e.key === 'PrintScreen') {
|
|
@@ -3225,10 +3194,9 @@
|
|
|
3225
3194
|
}
|
|
3226
3195
|
}, true);
|
|
3227
3196
|
|
|
3228
|
-
//
|
|
3197
|
+
// 8. Visibility change detection (tab switching for screenshots)
|
|
3229
3198
|
document.addEventListener('visibilitychange', function () {
|
|
3230
3199
|
if (document.hidden) {
|
|
3231
|
-
// User switched tabs - could be for screenshot tools
|
|
3232
3200
|
console.log('[Security] Tab hidden');
|
|
3233
3201
|
}
|
|
3234
3202
|
});
|
|
@@ -3236,30 +3204,6 @@
|
|
|
3236
3204
|
console.log('[Security] All protection features initialized');
|
|
3237
3205
|
})();
|
|
3238
3206
|
</script>
|
|
3239
|
-
|
|
3240
|
-
<!-- Security CSS for DevTools detection -->
|
|
3241
|
-
<style>
|
|
3242
|
-
.devtools-open #viewerContainer,
|
|
3243
|
-
.devtools-open #viewer,
|
|
3244
|
-
.devtools-open .pdfViewer {
|
|
3245
|
-
filter: blur(20px) !important;
|
|
3246
|
-
pointer-events: none !important;
|
|
3247
|
-
}
|
|
3248
|
-
|
|
3249
|
-
.devtools-open::after {
|
|
3250
|
-
content: 'Geliştirici araçları açıkken içerik görüntülenemez.';
|
|
3251
|
-
position: fixed;
|
|
3252
|
-
top: 50%;
|
|
3253
|
-
left: 50%;
|
|
3254
|
-
transform: translate(-50%, -50%);
|
|
3255
|
-
background: rgba(0, 0, 0, 0.9);
|
|
3256
|
-
color: #fff;
|
|
3257
|
-
padding: 30px 50px;
|
|
3258
|
-
border-radius: 10px;
|
|
3259
|
-
font-size: 18px;
|
|
3260
|
-
z-index: 99999;
|
|
3261
|
-
}
|
|
3262
|
-
</style>
|
|
3263
3207
|
</body>
|
|
3264
3208
|
|
|
3265
3209
|
</html>
|