Prevent PDF file from downloading and printing - security

I am trying to find a way to prevent a PDF from being printed or downloaded when view from web. Also, it is prefered that user cannot print screen.
I am thinking about converting those PDF files to Flash. Any other ideas?

Okay, I take back what I commented earlier. Just talked to one of the senior guys in my shop and he said it is possible to lock it down hard. What you can do is convert the pdf to an image/flash/whatever and wrap it in an iFrame. Then, you create another image with 100% transparency and lay it over top the iFrame (not in it) and set it to have a higher Z-value than the iFrame.
What this will do is that if they right click on the 'image' to save it, they will be saving the transparent image instead. And since the image 'overrides' the iFrame, any attempt to use print screen should be shielded by the image, and they should only be able to snapshot the image that doesn't actually exist.
That leaves only one or two ways to get at the file...which requires digging straight into the source code to find the image file inside the iFrame. Still not totally secure, but protected from your average user.

Ultimately you will need to:
Create Images for each page
Present those to the user on the web via your own interface (html, flash etc)
Keep in mind flash wont work on Apple devices if that's required.
A print screen will allow someone to recreate the low res image you present, and in this case you could add a watermark to the image.

That is not possible. Reading is downloading. When a user is reading a file, browser is downloading that file to temp. So even if you disable the download button, the user can click "File -> Save As" or copy that file from temp folder.
There are a few things you can do:
Method 1
The following code will embed a PDF without any toolbars and hide the print/download icons
<embed src="{URL_TO_PDF.PDF}#toolbar=0&navpanes=0&scrollbar=0" width="425" height="425">
Method 02
Using Google Drive
Right click on pdf and goto Share(below image)
Then go to Advanced option in left bottom
Tick Both check boxes. After copy embed link and paste it to your src. No download and Save drive option is not allowed

If you encrypt the PDF you can control how printable and changeable it is.
Print settings:
None
Low res (150 dpi)
high res (max dpi)
You can also prevent folks from copying/pasting from your PDF, and even do that while allowing screen readers access (visually impaired folks can still read your PDFs).
You haven't mentioned what you're using to build the PDFs so the details are up to you.
Alternative: You can create annotations that are only visible when printing. Create a solid box over the entire page that only shows up when printed -> No useful printing.
You might be able to do the same thing with layers (Optional Content Groups) as well, not sure.

Creating a video with QuickTime's screen capture or anything similar kind of defeats all the effort to protect your document file from being copied.

if you want to provide a solution, well, there just isn't one. You would have to be able stop the user running a program that can access the buffers in the GPU to prevent them grabbing a screen shot. Anything displayed on the screen can be captured.
If you decide to send a file where the contents are not accessible online, then you need to rely on the security that the end product/application uses. This will also be completely breakable for an extremely determined pserson.
The last option is to send printed documents in the post. The old fashioned way using a good courier service. Costs go up, time delays are inevitble - but you get exactly what you are after. A solution is not without its costs.
Always happy to point out the obvious :)

I wish I had an answer but I only have Part of one. And I cannot take credit for it but the way to get it is below.
This is a more serious issue than it is being given credit for from the sound of the replies. Everyone is automatically assuming that the content that needs protection is for public consumption. This is not always the case. Sometimes there are legal or contractual reasons that require the site owner to take all possible measures to prevent downloading the file. The most obvious one I can think of has already brought up. The “Action Option Bar” presented by the browser to on almost any file you can left click.
Adobe DRM does nothing about that and worse, Adobe Acrobat cannot even have its own abilities to “Save” blocked as part of the “DRM” protection. This option comes up even in Reader no matter what other security selections you have chosen.
In our case, Adobe Acrobat was purchased solely to provide some degree of protection for their own format. It is hard to believe that Adobe will let you prevent printing, prevent editing, prevent even opening without a password or you can really go all out and use a certificate for your encryption. Yet they have no options to prevent saving at any point, anywhere. Instead offering the consolation of telling you “Don’t worry: The copy they download without your permission will also have the same DRM on it as well”. Unfortunately that was not the sole purpose of the purchase and half a solution is no “solution” at all.
There are probably 100 programs that are actually sold just to remove the DRM from Adobe documents and even if not, the point was that the client specified that no downloads be allowed even by users who had access to the private site. Therefore the need to prevent the download to start with is not so hard to understand. While conversion to FLASH may give you the download protection, you lose all the rest. Unless I can find a way to prevent opening, saving etc for a Flash File. Next, is it possible to password protect a Flash file from opening when clicked on?
The “partial fix” that I was finally able to get to work as needed still only disables all the “right click” functions but it does include a nice “Warning Box” where I can explain that the User has already agreed NOT to download, print, save and so on just to have access to the page. I am not sure if I could post the code here or whether it is acceptable to paste links either but a Google search for "Maximus right click" will take you to it. And it was one of several examples, it just happened to be the one I could implement the easiest and worked better than the others. Credit where credit is due.
Another option I was given by someone was a product called “Flipping Book”. And the user above suggestions for “Atalasoft” ( I had already found that and have sent a request for more information). Hopefully it will be “The Solution” and I can implement it in time to help. It seems to me that this is a place where there is an obvious need for a one-step packaged solution and usually "The Laws of Nature" take care of such an Imbalance in short order. Yet my research has taken me through many years of posters all asking for the same thing. Looks like someone would be able to make a nice living off a “simple” way to add a little more "protection" to “PDFs” (or other documents, images etc) for the people who obviously are in need of it. If I find it, and it works, I'm buying it. :>)
I wish I had skills as a programmer because I have some pretty good ideas of ways to implement such a product, unfortunately, I do not know how to put these ideas into practical use.

Although we should agree that ultimately you cannot prevent some form of document capture (specially through screen capture technology either through phone or computer), the goal is to prevent direct download of original document. Some suggest you turn it into images, but this is not necessary. There is clearly a way, as several cloud services allow you to share pdf files, removing the download option, without converting the PDF to images (a superior method because it retains important properties like word search). Personally, as a user of Outlook email, I use the cloud service it provides, OneDrive. I just want to share the HTML code produced by OneDrive to share PDF files without download and right-click support. I am no expert on HTMl so cannot tell you exactly how it is done, but it might still provide you some insights. Here is the code for one particular PDF I shared (without private information and other bits that seemed unnecessary to me):
<!DOCTYPE html>
<html lang="en-us" dir="ltr">
<head><meta name="GENERATOR" content="Microsoft SharePoint" /><meta http-equiv="Content-type" content="text/html; charset=utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta http-equiv="Expires" content="0" /><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" /><title>
OneDrive for Business
</title><link rel="shortcut icon" href="/_layouts/15/images/odbfavicon.ico?rev=47" type="image/vnd.microsoft.icon" id="favicon" /></head>
<body style="margin: 0; padding: 0;">
<script nonce= '55c3d852-fe79-49b0-927d-e793a0ba3192' >if(!spfxPerfMarks){var spfxPerfMarks = {};} var markPerfStage=function(key) {if(window.performance && typeof window.performance.now === 'function'){spfxPerfMarks[key]=window.performance.now();} else{spfxPerfMarks[key]=Date.now();} if (window.performance && typeof window.performance.mark === 'function') {window.performance.mark(key);}};</script><script type="text/javascript" id="SuiteNavShellCore" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192" crossorigin="anonymous" src="https://shellprod.msocdn.com/api/shellbootstrapper/business/oneshell">
</script><script type="text/javascript" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192">
window.document.getElementById('SuiteNavShellCore').addEventListener('error', function() {
var scriptElem = document.getElementById('SuiteNavShellCore');
scriptElem.parentNode.removeChild(scriptElem);
var newScript = document.createElement('script');
newScript.setAttribute('type', 'text/javascript');
newScript.setAttribute('id', 'SuiteNavShellCore');
newScript.setAttribute('src', 'https://shellprod.msocdn.com/api/shellbootstrapper/business/oneshell');
newScript.setAttribute('crossorigin', 'anonymous');
newScript.async = true;
newScript.addEventListener('load', function() { (typeof markPerfStage === 'function' && markPerfStage('suiteNavScriptAsyncEnd')); if (window.executeSuiteNavOnce) { window.executeSuiteNavOnce() } });
newScript.addEventListener('error', function() { window.o365ShellScriptLoadError = arguments[0]; (typeof markPerfStage === 'function' && markPerfStage('suiteNavScriptError')); if (window.executeSuiteNavOnce) { window.executeSuiteNavOnce() } });
document.head.appendChild(newScript); });
</script><script type="text/javascript" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192">
window.o365ShellLoadPromiseResolve = undefined; window.o365ShellLoadPromiseReject = undefined; window.o365ShellRenderPromiseResolve = undefined; window.o365ShellRenderPromiseReject = undefined; window.o365ShellPostRenderPromiseResolve = undefined; window.o365ShellPostRenderPromiseReject = undefined; window.o365ShellLoadPromise = new Promise(function (loadResolve, loadReject) { window.o365ShellLoadPromiseResolve = loadResolve, window.o365ShellLoadPromiseReject = loadReject }); window.o365ShellRenderPromise = new Promise(function (renderResolve, renderReject) { window.o365ShellRenderPromiseResolve = renderResolve, window.o365ShellRenderPromiseReject = renderReject }); window.o365ShellPostRenderPromise = new Promise(function (prResolve,prReject) { window.o365ShellPostRenderPromiseResolve = prResolve, window.o365ShellPostRenderPromiseReject = prReject });var executeSuiteNav = function () {var suiteNavPlaceholder = document.createElement('div');suiteNavPlaceholder.id = 'SuiteNavPlaceholder';suiteNavPlaceholder.style = "min-height: 50px";document.body.insertBefore(suiteNavPlaceholder, document.body.firstChild);if (window.o365ShellScriptLoadError) {o365ShellLoadPromiseReject(window.o365ShellScriptLoadError);o365ShellRenderPromiseReject(new Error('SuiteNavLoadError'));o365ShellPostRenderPromiseReject(new Error('SuiteNavLoadError'));return; }o365ShellLoadPromiseResolve();var themeData;try { themeData = JSON.parse(localStorage.getItem('odSuiteNavthemedata')).themeData; }catch(err) { themeData = {Primary:'#0078D4'}; }(typeof markPerfStage === 'function' && markPerfStage('suiteNavRenderAsyncStart'));O365Shell.RenderAsync({top: 'SuiteNavPlaceholder', layout: 'Mouse', enableSearchUX: true, initialSearchUXVisibility: true, initialSearchUXPlaceholderText: 'Search', initialSearchUXSearchText: "",enableDelayLoading: true, collapseO365Settings: true, disableDelayLoad: false, disableShellPlus: false, isThinHeader: false, enableLegacyResponsiveBehavior: false, expectSearchBoxSettings: true, shellDataOverrides: {}, supportShyHeaderMode: false, initialRenderData: { AppBrandTheme: themeData, Culture: 'en-US', CurrentMainLinkElementId: 'ShellDocuments', IsConsumer: false, UserDisplayName: 'JOHN DOE', UserID: '100320009e7b358d', WorkloadId: 'Sharepoint', ShellBootHost: 'https://shellprod.msocdn.com', EnableVanillaSearchBox: true }},function () {(typeof markPerfStage === 'function' && markPerfStage('suiteNavRenderAsyncEnd'));o365ShellRenderPromiseResolve();},function () {(typeof markPerfStage === 'function' && markPerfStage('suiteNavPostRender'));o365ShellPostRenderPromiseResolve();},function (error) {(typeof markPerfStage === 'function' && markPerfStage('suiteNavRenderAsyncErrorEnd'));o365ShellRenderPromiseReject(error); o365ShellPostRenderPromiseReject(error);});};
</script><script type="text/javascript" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192">
var params = window.location.search.substring(1).split('&') || [];
var shouldExecuteSuiteNav = true;
shouldExecuteSuiteNav &= params.indexOf('p=2') === -1;
shouldExecuteSuiteNav &= params.indexOf('cl=true') === -1;
shouldExecuteSuiteNav &= params.filter(function (x) { return x.indexOf('parent') === 0; }).length === 0;
try { shouldExecuteSuiteNav &= window.parent === window; } catch(err) { shouldExecuteSuiteNav = false; }
if (shouldExecuteSuiteNav) { executeSuiteNav(); }
</script>
</body>
<script type="text/javascript">
try {
(function() {
var a = navigator.userAgent.toLowerCase();
var i = a.indexOf("msie");
if (-1 !== i) {
var v = parseInt(a.substring(i + 5));
if (v <= 8 && Boolean(document.documentMode) && document.documentMode <= 8) {
var d = new Date(); d.setTime(d.getTime() + 31536000000);
document.cookie = "odbnu=0;expires=" + d.toUTCString() + ";path=/";
window.location.href = window.location.href.replace(/\/onedrive\.aspx/i, '/start.aspx#/Documents/Forms/All.aspx');
}
}
})();
} catch(e) {}
</script>
<script type="text/javascript" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192">
SOME PRIVATE STUFF HERE
</script><link rel="preconnect" href="https://spoprod-a.akamaihd.net" crossorigin /><script type="text/javascript">
!function(){if('PerformanceLongTaskTiming' in window){var g=window.__tti={e:[]};g.o=new PerformanceObserver(function(l){g.e=g.e.concat(l.getEntries())});g.o.observe({entryTypes:['longtask']})}}();
</script><script type="text/javascript">
var g_responseEnd = new Date().getTime();window['FabricConfig'] = { fontBaseUrl: ''};window['__odsp_culture'] = 'en-us';window['__odspSriHashes'] = {"listviewdataprefetch-mini-c82c051f.js":"sha256-GCNR9Rk+cuSJfvbszuhs5ZBaUs5tQ2RdzzJTteHOXGk=","reactandknockout-mini-584215d6.js":"sha256-ICjqvvD9qHiKbj5xYFNGC/JsgNcqNRRL1t3kW4RVioI=","aria-mini-2e5a74c4.js":"sha256-CbCwYga9yHE+t1OvB+NHHDdH2rxSfY6KJkCMiUpXQjw=","spectreviewer-mini-9c641fce.js":"sha256-tqmAhKxEONjZOpZuGrbo8VdnLx6kRH+Xfhjrcchv2+4=","babylonjs-mini-22e57381.js":"sha256-T6IgL4CdkolwNC0L4tG6d+G07Bhuc7bI1pSIShdrTUk=","sp-http_odb-mini-21a5eb98.js":"sha256-mTfdqB83ALG/d2z8krhrUugjXBzFQ/bzPfUIgcayACg=","onedriveappfontsplt-mini-ce0e18ec.js":"sha256-+ockQ4cjstrmVqBPVRH8C9Z9M0ZJbyQxHQ/cm/ukBOI=","onedriveappfontsdeferred-mini-3771cbb9.js":"sha256-qXZjhCWJDNPCbbXRIwDt1cqIyqzQKqROnwdASmSsoGw=","odbonedriveapp-mini-11081db7.js":"sha256-j/CkxuEVbtMOL5PRKZ05dZURZ/aNH9tk6vnMj6ei/lk=","en-us/
</script><script type="text/javascript">
window['moduleNameMapping']={"odsp-next/providers/operation/OperationProvider":"Rq"};
</script><script type="text/javascript" data-import-link="https://spoprod-a.akamaihd.net/files/odsp-common-library-prod_2019-02-15_20190219.002/require.js" id="requireJsString">
SOME VERY LONG FUNCTION CODE
</script><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/listviewdataprefetch-mini-c82c051f.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/reactandknockout-mini-584215d6.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/odbonedriveapp-mini-11081db7.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/en-us/odbonedriveapp-mini.resx-7f957d5c.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/odbonedrive-mini-5e8b1855.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/en-us/odbonedrive-mini.resx-374bb468.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/odbfiles-mini-9aaee23c.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/en-us/odbfiles-mini.resx-250da06d.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/odbitemsscope-mini-5070e33c.js" rel="preload" crossorigin="anonymous" as="script" /><link href="https://spoprod-a.akamaihd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/en-us/odbitemsscope-mini.resx-ff223e24.js" rel="preload" crossorigin="anonymous" as="script" /><script type="text/javascript" id="requireConfig">
!function(){
var backupBaseUrl = 'https://az741266.vo.msecnd.net/files/odsp-next-prod-amd_2020-06-12_20200612.001/';
window.__backupBaseUrl = backupBaseUrl;
var failOverState = window.__cdnFailOverState = {
baseUrlFailedOver: false,
modulesFalledBack: []
};
function processConfigToSupportFailOver(config) {
var paths = {};
for (var bundleId in config.bundles) {
var bundlePath = config.paths[bundleId];
var fallbackPaths = [bundlePath, backupBaseUrl + bundlePath];
for (var _i = 0, _a = config.bundles[bundleId]; _i < _a.length; _i++) {
var moduleName = _a[_i];
paths[moduleName] = fallbackPaths;
}
}
return {
paths: paths,
shim: config.shim,
deps: config.deps,
baseUrl: config.baseUrl,
waitSeconds: config.waitSeconds,
onNodeCreated: config.onNodeCreated,
enforceDefine: config.enforceDefine,
onPathFallback: function (options) {
var moduleId = options.moduleId;
var config = options.config;
if (moduleId && config && config.deps && config.deps.indexOf(moduleId) >= 0) {
var failedModules = failOverState.modulesFalledBack;
failedModules.push(moduleId);
if (!failOverState.baseUrlFailedOver && failedModules.length >= 2) {
require.config({
baseUrl: backupBaseUrl
});
failOverState.baseUrlFailedOver = true;
}
}
}
};
}
var config = {paths:{"listviewdataprefetch-mini":"listviewdataprefetch-mini-c82c051f","reactandknockout-mini":"reactandknockout-mini-584215d6","aria-mini":"aria-mini-2e5a74c4","spectreviewer-mini":"spectreviewer-mini-9c641fce","babylonjs-mini":"babylonjs-mini-22e57381","sp-http_odb-mini":"sp-http_odb-mini-21a5eb98","onedriveappfontsplt-mini":"onedriveappfontsplt-mini-ce0e18ec","onedriveappfontsdeferred-mini":"onedriveappfontsdeferred-mini-3771cbb9","odbonedriveapp-mini":"odbonedriveapp-mini-11081db7","odbonedriveapp-mini.resx":"en-us/odbonedriveapp-mini.resx-7f957d5c","odbonedrive-mini":"odbonedrive-mini-5e8b1855","odbonedrive-mini.resx":"en-us/odbonedrive-mini.resx-374bb468","odbbasepage-mini":"odbbasepage-mini-8d7dea71","odbfiles-mini":"odbfiles-mini-9aaee23c","odbfiles-mini.resx":"en-us/odbfiles-mini.resx-250da06d","odbuploadmanager-mini":"odbuploadmanager-mini-168f0ee8","odbuploadmanager-mini.resx":"en-us/odbuploadmanager-mini.resx-660b735c","odbreactcontrols-mini":"odbreactcontrols-mini-6f323ced","odbreactcontrols-mini.resx":"en-us/odbreactcontrols-mini.resx-c7ec26e2","odbdeferred-mini":"odbdeferred-mini-b9def3da","odbdeferred-mini.resx":"en-us/odbdeferred-mini.resx-d1f98f82","odblivepersonapicker-mini":"odblivepersonapicker-mini-414c6f81","odbdebugwindow-mini":"odbdebugwindow-mini-2f4ef22c","odbfilepicker-mini":"odbfilepicker-mini-2f5a2203","odbfilepicker-mini.resx":"en-us/odbfilepicker-mini.resx-3562db06","odbembed-mini":"odbembed-mini-8638d6c3","odboneup-mini":"odboneup-mini-3086899d","odboneup-mini.resx":"en-us/odboneup-mini.resx-a7d40d5e","odbpdf-mini":"odbpdf-mini-7d046eb1","odbpdf-mini.resx":"en-us/odbpdf-mini.resx-e5e07b77","odbwrs-mini":"odbwrs-mini-2c0b0a8b","odbsharepage-mini":"odbsharepage-mini-e62fc2f8","odbtextfileeditor-mini":"odbtextfileeditor-mini-000ede78","odbtextfileeditor-mini.resx":"en-us/odbtextfileeditor-mini.resx-259dbac3","odbfilerequestpage-mini":"odbfilerequestpage-mini-db0e14b3","odbfilerequestpage-mini.resx":"en-us/odbfilerequestpage-mini.resx-8e83db21","odbtiles-mini":"odbtiles-mini-a111ffa2","odbtiles-mini.resx":"en-us/odbtiles-mini.resx-4fae993b","odbsites-mini":"odbsites-mini-c5563389","odbsites-mini.resx":"en-us/odbsites-mini.resx-1b3b4aeb","odbitemvideoplayer-mini":"odbitemvideoplayer-mini-b7a61bf1","odbitemvideoplayer-mini.resx":"en-us/odbitemvideoplayer-mini.resx-983d47a8","odbexecutors-mini":"odbexecutors-mini-f93c0ada","odbexecutors-mini.resx":"en-us/odbexecutors-mini.resx-853081e6","odbdeferredcontrols-mini":"odbdeferredcontrols-mini-29643ad1","odbdeferredcontrols-mini.resx":"en-us/odbdeferredcontrols-mini.resx-d50ca5ed","odbnotifications-mini":"odbnotifications-mini-04da08b9","odbpushchannel-mini":"odbpushchannel-mini-38d90d10","odberror-mini":"odberror-mini-12596c1d","odberror-mini.resx":"en-us/odberror-mini.resx-cf31139d","odbrestore-mini":"odbrestore-mini-950ba62f","odbrestore-mini.resx":"en-us/odbrestore-mini.resx-3a5cbe8e","odbsettingsbasepage-mini":"odbsettingsbasepage-mini-d6c5acdd","odbsettingsbasepage-mini.resx":"en-us/odbsettingsbasepage-mini.resx-b5949852","odbsettings-mini":"odbsettings-mini-ddeab1d1","odbitemsscope-mini":"odbitemsscope-mini-5070e33c","odbitemsscope-mini.resx":"en-us/odbitemsscope-mini.resx-ff223e24","odbitemsscopedeferred-mini":"odbitemsscopedeferred-mini-f918897a","odbitemsscopedeferred-mini.resx":"en-us/odbitemsscopedeferred-mini.resx-af61a995","odbmobileappupsellbasepage-mini":"odbmobileappupsellbasepage-mini-723e546a","odbemptyfolderroot-mini":"odbemptyfolderroot-mini-f9f096eb","odbwinappcommunicator-mini":"odbwinappcommunicator-mini-60ab2c1a","odbcreatesite-mini":"odbcreatesite-mini-5400c9ec","odbcreatesite-mini.resx":"en-us/odbcreatesite-mini.resx-d9c236d6","odb-functional-tests-mini":"odb-functional-tests-mini-41e66bd6","odbhighcharts-mini":"odbhighcharts-mini-ce7056aa","odbclientform-mini":"odbclientform-mini-106b2b9f","odbclientform-mini.resx":"en-us/odbclientform-mini.resx-356af9e8","odbfloodgate-mini":"odbfloodgate-mini-061846b3","odbfloodgate-mini.resx":"en-us/odbfloodgate-mini.resx-610e7422","odbpowerapps-mini":"odbpowerapps-mini-c5977eac","msflowsdk":"msflowsdk-8689f64f","power-app":"power-app-86d2bb4d"},"directional-navigation":{}},deps:["bL3","f","bvB","a6o","buW","buZ","bfi"],baseUrl:"https:\u002f\u002fspoprod-a.akamaihd.net\u002ffiles\u002fodsp-next-prod-amd_2020-06-12_20200612.001\u002f",waitSeconds:0,onNodeCreated:function(n,c,m,u) {
n.setAttribute("crossorigin","anonymous");
var urlParts = u.split('/');
var fileName = urlParts[urlParts.length - 1];
var odspSriHashes = window.__odspSriHashes;
var integrity = odspSriHashes && (odspSriHashes[window.__odsp_culture + '/' + fileName] || odspSriHashes[fileName]);
if (integrity) {
n.setAttribute("integrity",integrity);
}
},enforceDefine:true};
var newConfig = processConfigToSupportFailOver(config);
require.config(newConfig);
}();
</script><script type="text/javascript">
window["_spModuleLink"]={"buildNumber":"odsp-next-prod-amd_2020-06-12_20200612.001","manifestName":"ODBOneDrive","scenarioName":"ODBOneDrive","usingRedirectCookie":false,"bugLinkFormat":null,"ulsLinkFormat":null};
</script>
</html>
<script type="text/javascript" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192">
var g_duration = 92;
var g_iisLatency = 2;
var g_cpuDuration = 72;
var g_queryCount = 6;
var g_queryDuration = 18;
var g_requireJSDone = new Date().getTime();
</script><script type="text/javascript">
var _spOneDrivePageDataCache = {"SPHomeWeb:sites/feed":{"cacheContext":{"ListItemId":3,"Hash":null,"MySiteUrl":null,"Time":"2020-05-28T15:24:51.0000000Z","Version":null},"cacheValue":null},"ODBWeb.sites/feed":{"cacheContext":{"ListItemId":4,"Hash":"7iItaPeKRTNyNthQTkF2/CvVyjcOTjNOkCsKnNsKarY=","MySiteUrl":null,"Time":"2020-05-28T15:25:03.0000000Z","Version":"1.0"},"cacheValue":"{\"Items\":[],\"Type\":\"ItemsList\"}"},"ODBWeb.substrate.recommended":{"cacheContext":{"ListItemId":5,"Hash":null,"MySiteUrl":null,"Time":"2020-05-28T15:24:51.0000000Z","Version":null},"cacheValue":null}};
</script>
<script type="text/javascript" nonce="55c3d852-fe79-49b0-927d-e793a0ba3192">
var g_deferDataLoadTime = new Date().getTime();var g_payload = {"parameters":{"__metadata":{"type":"SP.RenderListDataParameters"},"RenderOptions":1513223,"AllowMultipleValueFilterForTaxonomyFields":true, "AddRequiredFields":true}}; var g_listData = {"wpq":"","Templates":{},"ListData":{ "Row" :
[] OTHER SETTINGS WITH PRIVATE STUFF...
}};if (typeof DeferredListDataComplete != "undefined" && DeferredListDataComplete) { DeferredListDataComplete(); }
</script>

I suggest to modify pdf.js: remove the download button, convert pdf (at backend part) to some intermediate format of pdf.js and put watermark also at server side.

(disclaimer - I work for Atalasoft)
If you present your PDF documents with the Atalasoft web image viewer, you can prevent the PDF from being downloaded. You could also control printing from javascript on the client side.

In my opinion the other proposed solution is.
Convert your PDF book to HTML,
Show the html book in Iframe
This approach will prevent the users to download the file.

Convert pdf to image.
Use image tag to display the image.
Disable right click on the image.

Related

How to retrieve Vector Tiles from Mapbox with d3.js and convert to geojson?

I am trying to replicate the example from Mike Bostock: https://observablehq.com/#d3/mapbox-vector-tiles
Since the language of Observable is not native Javascript, I am unable to get the example running.
Especially, the following two functions I am unable to get to work:
VectorTile = (await require("https://bundle.run/#mapbox/vector-tile#1")).VectorTile
Protobuf = require("pbf#3/dist/pbf.js")
require() is not a Javascript command. So, how can I get these two libraries?
What I tried:
Insert the libraries via <script></script> tags
Loading with await:
let VectorTile = await fetch('https://bundle.run/#mapbox/vector-tile#1.3.1');
let Protobuf = await fetch('https://unpkg.com/pbf#3.0.5/dist/pbf.js');
I am not sure if require() comes from node.js. So I played around with node.js but did not find a working solution either.
So, my question is: How can I get the example from Mike Bostock to work? Or in more general manner: How should I load vector tiles from Mapbox that I can convert them to geojson format as Mike is it doing in this example?
Regarding your first question, in order to get Mike Bostock's example to work you can keep in mind considerations:
Promises are something that Observable takes care of automatically, while node.js or JavaScript in browser does not, so you should take care of them
Add all the necessary libraries, while keeping in mind that the way you call them might be different from how Mike does so. As, for example, by default you should use Pbf, not Protobuf if you use pbf library (And yes require() comes from node.js)
For #mapbox/vector-tile library notice that it exports 3 objects, while you need VectorTile function (in node.js you could just use require().VectorTile). You can see how I've done it below for JavaScript in html
Finally you will need to insert generated svg code into html in order to display it, this is also something that Observable does automatically
I can't really tell how you 'should' load vector tiles, as I don't have much expertise in this particular aria. However, below I converted Mike Bostock's example to javascript, so you can see how it works outside of Observable.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
Map:
<div id='map'></div>
</div>
<script src="https://d3js.org/d3-array.v2.min.js"></script>
<script src="https://d3js.org/d3-geo.v2.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-tile#1"></script>
<script src="https://d3js.org/d3-dsv.v2.min.js"></script>
<script src="https://d3js.org/d3-fetch.v2.min.js"></script>
<script src="https://unpkg.com/pbf#3.0.5/dist/pbf.js"></script>
<script src="https://bundle.run/#mapbox/vector-tile#1.3.1"></script>
<script>let VectorTile = _mapbox_vectorTile.VectorTile</script>
<script>
height = 600;
width = 954;
API_KEY = 'cfNfEQR1Qkaz-6mvWl8cpw';// Sign up for an API key: https://www.nextzen.org
projection = d3.geoMercator()
.center([-122.4183, 37.7750])
.scale(Math.pow(2, 21) / (2 * Math.PI))
.translate([width / 2, height / 2]).precision(0);
path = d3.geoPath(projection)
tile = d3.tile()
.size([width, height])
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]));
function filter({features}, test) {
return {type: "FeatureCollection", features: features.filter(test)};
};
function geojson([x, y, z], layer, filter = () => true) {
if (!layer) return;
const features = [];
for (let i = 0; i < layer.length; ++i) {
const f = layer.feature(i).toGeoJSON(x, y, z);
if (filter.call(null, f, i, features)) features.push(f);
}
return {type: "FeatureCollection", features};
}
tiles_pr = Promise.all(tile().map(async d => {
d.layers = new VectorTile(new Pbf(await d3.buffer(`https://tile.nextzen.org/tilezen/vector/v1/256/all/${d[2]}/${d[0]}/${d[1]}.mvt?api_key=${API_KEY}`))).layers;
return d;
}))
tiles_pr.then(
function(tiles){
//console.log(tiles)
map = `<svg viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg">${tiles.map(d => `
<path fill="#eee" d="${path(geojson(d, d.layers.water, d => !d.properties.boundary))}"></path>
<path fill="none" stroke="#aaa" d="${path(geojson(d, d.layers.water, d => d.properties.boundary))}"></path>
<path fill="none" stroke="#000" stroke-width="0.75" d="${path(geojson(d, d.layers.roads))}"></path>
`)}
</svg>`
document.getElementById('map').innerHTML=map;
}
);
</script>
</body>
</html>

Anki and AnkiDroid: Importing JSON from collection.media with javascript

I want to import files from collection.media that are not sound, image, or video. For example I'd like to import a JSON file.
I put the file _script.jquery-3.3.1.min.js and _data.json in my collection.media folder.
On Anki Desktop (Ubuntu), the following works:
<script src="_script.jquery-3.3.1.min.js"></script>
<script>
$.getJSON('_data.json', function(data) {
// succeeds on Anki Desktop, fails on AnkiDroid
});
</script>
(Note on Anki Desktop 2.0.47 I am using the JS Booster plugin).
On AnkiDroid, the situation is different. JQuery loads just fine in the script tag. However, $.getJSON fails to find the _data.json file.
I'd like to use _data.json on many cards/notes.
How can I import non-media, non-js files from collection.media in javascript, in a way that works both in Anki Desktop and AnkiDroid?
I have found some working answer for this.
To get character data in AnkiDroid card templates. (OFFLINE)
As we can access js and image file using this
<script src="some-js-file.js"></script>
<img src="some-image.png"></img>
To access json
I have tried same steps but getting CORS error so I used next steps.
<!-- It will give CORS error -->
<script src="我.json" type="application/json"></script>
With example,
To access 我.json file
Copy contents of 我.json into a javascript file 我.js, with any variable name,
var char_data = {"strokes":["M 350 571 Q 3....}
Add following tag to access that js file
<!-- Note : file type & name -->
<script src="我.js" type="text/javascript"></script>
Now also change code in _hanzi-writer.min.js
To change code, first beautify code using this https://beautifier.io, then make following change
a) Remove the link to load from internet
b) Change this 200 != r.status and replace/add this
JSON.parse(JSON.stringify(char_data))
( May be more good replacement can be done here )
....
....
// Note : char_data variable come from 我.js file
r.overrideMimeType && r.overrideMimeType("application/json"), r.open("GET", "", !0), r.onerror = function(t) {
....
....
4 === r.readyState && (200 != r.status ? i(JSON.parse(JSON.stringify(char_data))) : 0 !== r.status && n && n(r))
....
....
So final script will be like this
Front side of card
{{Pinyin}}
<div id="character-target-div"></div>
<script src= "我.js" type="text/javascript"></script>
<script>
var data = JSON.stringify(char_data);
console.log(data);
</script>
<script src="_hanzi-writer.min.js"></script>
<script>
var writer = HanziWriter.create('character-target-div', '我', {
width: 150,
height: 150,
showCharacter: false,
padding: 5
});
writer.quiz();
</script>
Above all the steps are for single file 我.js
To access other character repeat the same.
For similar issues view my code
https://github.com/infinyte7/Anki-xiehanzi
https://github.com/infinyte7/hanzi-writer-data-in-javascript
I assume this is related to how AnkiDroid handles collections.media files. If so, this might be a bug. A really hackish workaround could be to rename the file to .svg so that AnkiDroid treats it as an image and lets it through.

Office 365 outlook appointment addin does not start

We are encountering problems when trying to load our outlook appointment addin. Our command shows up in the ribbon ui and the addin is trying to start and we can trace the calls to our wev-app. We are not getting any errors, 404 or 500 in the tracing and the service responds with our first html-page containing a text and a button to initiate our authentication.
But after the html is returned outlook just stops the spinner for the addin and nothing is showed. Is there any good ways to debug this to understand what is happening?
The html-page is very simple and only contains the code below.
<head>
<title>Office-bokning</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.components.min.css">
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
<!--[authentication-popup-script]-->
<script>
startCheck = function () {
var checkCode = setInterval(function () {
localStorage.setItem('dummy', "dummy");
localStorage.removeItem('dummy');
var code = localStorage.getItem('code');
var externalProviderUserId = localStorage.getItem('externalProviderUserId');
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var fallbackCode;
var fallbackExternalProviderUserId;
if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
fallbackCode = readCookie('NAME_OF_COOKIE');
fallbackExternalProviderUserId = readCookie('externalProviderUserId');
}
console.log("code " + code);
if (code || fallbackCode) {
clearInterval(checkCode);
var http = new XMLHttpRequest();
var url = [URL]
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "text/plain");
//var that = this;
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
localStorage.removeItem('code');
localStorage.removeItem('externalProviderUserId');
window.location.href = "[URL]";
//location.reload();
}
}
http.send(params);
}
}, 1000);
}
startCheck();
</script>
</head>
<body class="container-fluid" style="padding-left: 0px; padding-right: 0px; height: 100%">
<p>
Some text describing the addin...
</p>
<!--[popup-button]-->
<script>
Office.initialize = function (reason) {
console.log("authorize office init" + reason);
var butan = document.getElementById('loginButton');
if (butan)
butan.style.display = 'block';
}
function commandFunction(event) {
event.completed();
}
</script>
</body>
TL;DR : It seems you want to pop up a page for auth. Use the displayDialogAsync API to do that.
Looking at your code, I don't see anything wrong with it. Moreover, the behavior you described is actually correct according to the code you have.
I see that you have a function named "commandFunction" that takes in an "event" parameter. My guess is that you have an ExecuteFunction in your manifest that calls commandFunction.
So when a user clicks on your add-in's button in the ribbon ui of an appointment window, Outlook will load your html webpage, invoke "Office.initialize", show a default spinner for your app just above the "Subject" field of the appointment window, and then call "commandFunction". The only code inside this function is "event.completed", so Outlook calls that code, which basically ends the execution of your app, at which point Outlook removes the default spinner to signal completion. That's exactly what you are experiencing.
You have to run any relevant code inside "commandFunction" before calling "event.completed". So for example, you can add code that will add a notification message/infobar to the appointment before calling "event.completed". Sample code below:
function commandFunction(event)
{
Office.context.mailbox.item.notificationMessages.addAsync
(
"some_unique_id_such_as_a_guid",
{
type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,
persistent: false,
message: "hello world",
icon: "default_icon"
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
It appears that you want to open an html window for the user to authenticate before proceeding with the execution of your app. In that case, you should use the "displayDialogAsync" API by calling it inside "commandFunction" before "event.completed". This will open an IE window that points to authentication page URL. Sample code below:
function commandFunction(event)
{
Office.context.ui.displayDialogAsync
(
"https://ur/to/auth/page",
{
width: 50,
height: 45,
requireHTTPS: true
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
The documentation for the displayDialogAsync API is at: https://github.com/OfficeDev/office-js-docs/blob/master/reference/shared/officeui.md
For debugging, open IE, go to 'Internet Options' -> 'General tab' -> click on 'Settings' button to open the 'Website Data Settings' window. In the 'Temporary Internet Files' tab, under 'Check for newer versions of stored pages', select 'Every time I visit the webpage'. Click Ok.
Now go to 'Advanced' tab -> 'Settings' section and uncheck the following:
Disable script debugging (Internet Explorer)
Disable script debugging (Other)
Then check the following:
Display a notification about every script error
Then add "debugger;" as the first line in "commandFunction":
function commandFunction(event)
{
debugger;
// add other code below...
}
This will prompt you to debug your code when you run the app. And you can debug in Visual Studio and go through your code if you have any other issues.
The HTML you pasted doesn't have a reference to Office.js: <script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>

Avoiding Website content select and copy

I am using Drupal 6. In drupal how to avoid the user to copying the web page contents.How to disable it.
Thanks
Ultimately ... you can't.
Even if you try some fancy JavaScript or some fancy image over, etc., a user can just press Ctrl+A (select all) and then Ctrl+C (copy). There is a plethora of ways to get information from a web-site such as development environment (FireBug), alternative agents (wget/curl), or even using a browser not "protected" with the scheme.
Bottom line ... the only way to prevent someone from "keeping" that data is by not giving them access to begin with. Alternatively, make the user(s) sign an NDA/agreement and hire lawyers :-)
Happy doing productive things.
If all that is desired is prevent a "select" with a mouse, then an img-over may work. Alternatively, send back non-text (e.g. images containing the text) content and/or embed the content into Flash or another relatively controlled plug-in.
There is a java script code to disable the content copy.
I pasted that code into body of the page and set input format into php code.
<script type="text/javascript">
var donotconsidortag = ["input", "textarea", "select"]
donotconsidortag = donotconsidortag.join("|")
function unableToSelect(e) {
if (donotconsidortag.indexOf(e.target.tagName.toLowerCase()) == -1)
return false
}
function ableToSelect() {
return true
}
if (typeof document.onselectstart != "undefined")
document.onselectstart = new Function("return false")
else {
document.onmousedown = unableToSelect
document.onmouseup = ableToSelect
}
</script>
For the particular content type use " content template " module and past the above code in to content template's textarea.In this we can disable the content select option for whole content type(For ex:Page or Story)
<SCRIPT language=JavaScript>
var message = "function disabled";
function rtclickcheck(keyp){ if (navigator.appName == "Netscape" && keyp.which == 3){ alert(message); return false; }
if (navigator.appVersion.indexOf("MSIE") != -1 && event.button == 2) { alert(message); return false; } }
document.onmousedown = rtclickcheck;
</SCRIPT>
There is no way to prevent a determined user from accessing the content of your web page. Tools like firebug, and a plethora of screen capture software easily circumvent any such attempts.
To make it difficult for unsophisticated or lazy users, you could overlay a transparent 1x1 image over the top of the entire page, or content you are trying to protect.
<img src="transparent.png" style = "width:100%; height:100%;position:absolute;" />

Prevent onbeforeunload from being called when clicking on mailto link

Is there anyway to prevent onbeforeunload from being called when clicking on mailto link in chrome.
In FF, Safari, IE it is working fine.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js">
google.load("jquery", "1.3.2");
</script>
<script type="text/javascript">
$(document).ready(function(){
window.onbeforeunload = confirmExit;
});
function confirmExit() {
return "Are you sure?";
}
</script>
</head>
<body>
Mail Link
</body>
</html>
What about a workaround?
$(document).ready(function(){
mailtoClicked = false;
window.onbeforeunload = confirmExit;
//Test if browser is Chrome
if (/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())) {
$('a[href^=mailto]').click(function() {mailtoClicked = true;});
}
});
function confirmExit() {
if (!mailtoClicked) {
return "Are you sure?";
} else {
mailtoClicked = false;
}
}
Demo.
Here is a proposed solutions that looks reasonable
http://www.ilovebonnie.net/2009/09/23/how-to-use-onbeforeunload-with-form-submit-buttons/
UPDATE (link is dead) - Copied contents from Google Cache
How to Use onbeforeunload with Form Submit Buttons
September 23rd, 2009 — Geekery
While doing some programming I came across an interesting predicament. While I understand it’s evil to make it hard for a user to leave a page, I’m not here to argue the merits (or lack thereof) of onbeforeunload.
On a particular form, we are forcing the browser to not cache the information to avoid potential AJAX/JavaScript problems if they should leave the form and come back as browsers don’t all act the same (eg IE leaves checkboxes checked but doesn’t remember changes that have occurred to the page due to JavaScript). As such, we warn our users when they’re about to leave the order form to let them know they’ll need to fill it in again.
The function was simple enough:
window.onbeforeunload = function () {
return "You are about to leave this order form. You will lose any information...";
}
Unfortunately, this would also be triggered if the user submitted the form which, is obviously not what we want. After searching around on the Internet I came across a simple solution that I thought I would share:
// Create a variable that can be set upon form submission
var submitFormOkay = false;
window.onbeforeunload = function () {
if (!submitFormOkay) {
return "You are about to leave this order form. You will lose any information...";
}
}
Since onclick appears to register before onsubmit when clicking a submit button, we can add a little variable declaration to our submit button so that submitFormOkay will be set to true before the form submission happens:
<input type="submit" id="submit_button" onclick="submitFormOkay = true;">

Resources