Accessing public files via javascript SDK - google-drive-api

I am working on an application where a user can create a list, and share it publicly. The contents of the list is rendered by my site as a webpage, but exists also as a text file in the users drive who created it. Everything is handed by javascript, and works well, however I am currently using the https://www.googleapis.com/auth/drive scope.
This is a very scary permission to have, so I would like to drop it. However, when the user trying to read the file, if they only have the https://www.googleapis.com/auth/drive.file scope, the shared file (accessed by id) doesn't exist for them until I run them though the sharing flow.
My guess is that although this was a file created in my application, that file was never opened by the viewing user in my application, so it doesn't qualify under that scope. This seems a bit silly, because anyone (even if they are not logged in as any user) could download the file from google using only its id.
I want to avoid running them through the share-link flow, because if the user hasn't logged into my application yet, they are more or less stranded at that screen. The app isnt installed as a viewer for that filetype for them, so they aren't presented with it as a suggested app to use to open it.
Am I doing something wrong, or is there really no way to support this seemingly very common use case of enabling a user to share links to their files though the app open url?
I dont see why I should need full access to the user's drive as I'm trying to access a file that isn't even in their drive.
Note: I do also have the realtime-api mounted on top of the file, which is also working, but shoudln't really have anything to do with the basic sharing.
Some relevant code snippets creating and setting permissions on the file:
Create The File
gapi.client.load('drive', 'v2', function() {
var insertHash = {
'resource': {
mimeType: 'application/vnd.mysite.com',
title: title
};
};
gapi.client.drive.files.insert(insertHash).execute(next);
});
Grant Everyone Permissions
gapi.client.drive.permissions.insert({
fileId: $scope.id, resource: {
type: 'anyone',
role: 'writer'
}
}).execute(function(resp) {
console.log(resp);
});
Try to access the file as a viewer, fails with out https://www.googleapis.com/auth/drive scope
gapi.client.drive.files.get({fileId: $scope.id}).execute(function(resp) {
console.log(resp);
next(resp);
});

Related

Does the firebase web SDK need to be in every html file i use?

The firebase web sdk code is already in my index.html. If i wanted to redirect it to another html file (eg: account.html), would i need to re-paste all the firebase sdk code?
For reference, here's the default sdk code firebase tells you to paste at the start of the app:
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.7.0/firebase-app.js"></script>
<!-- More SDK's at https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.7.0/firebase-analytics.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "xyz",
authDomain: "xyz.firebaseapp.com",
databaseURL: "https://xyz.firebaseio.com",
projectId: "xyz",
storageBucket: "xyz.appspot.com",
messagingSenderId: "xyz",
appId: "xyz",
measurementId: "G-xyz"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
</script>
The short answer is yes. You need to include the Firebase SDK in every HTML page where you want to be able to use it.
The Firebase SDKs are often used in conjunction with JavaScript libraries that enable the "Single-Page App" pattern, where navigating between different pages does not actually trigger a new page load in the browser. An oversimplified explanation is that you'd have a single index.html page that always loads no matter what URL the user visits on your site, and JavaScript would intercept link clicks etc. and change the URL appropriately as your user navigates the site. This can have performance advantages over a full page reload.
Alternatively you could export your firebase SDK code snippet into another seperate .js file and then include it in each of your html files. That way you don't need to repeat yourself with lines of code.
From my beginner's perspective, I'd just ask yourself:
"Does this page use any Firebase services?" i.e., Does it need to know details about a user (signed in, uid, etc)? Does it call a Cloud Function? Does it read or write to a Firebase database?
If yes, yes, you'll need the relevant SDKs loaded. If no, like it's just a random page of content hosted by Firebase hosting, then no, you don't need it on that page.
Examples:
If you have a user logged in, probably you'd track that user all throughout your site, to provide them access to personalized content and account options, so you'd need Firebase loaded all throughout.
But, if for some reason you have an isolated page that needs to call a cloud function, but other pages that don't, then I don't see why you'd need to have Firebase on that page.
You didn't ask about Firebase hosting specifically, but since that confused me when I set it up, I'll just mention that you can host through Firebase hosting and still not load the Firebase SDKs if you're not using Firebase services on a given page.
Hope that helps!

Playing local HTML5 audio from an external server on desktop

My problem corresponds with the following hypothetical situation:
I have a website with a blog, which stores a playlist of music (just the filenames). I can edit this playlist remotely, for example from my phone when I am on the move. The content of the website is stored in a database on the server (MySQL), which cannot be accessed remotely.
When I get home and I am writing on my blog, I want to play the files in the list, on the same website, by using HTML5 audio. The files are located on my local computer at home. Hence I want to access these local files through my website.
An example of how I am addressing a local file is file:///M:/music.mp3.
The whole set-up works if I work from localhost, so I don't think it is a coding issue.
The problem is that both Firefox and Chrome, my favourite browsers, do not allow third party websites to access my local files without my active input.
It makes sense that the construction above is prevented by user agents due to security issues. I was hoping to find a solution in the fact that I use browser integrated HTML5 audio; IMO, there would be no security issue since the files that are loaded by HTML5 audio cannot be accessed via DOM, so some proper coding of the browsers would have left some breathing room here.
Some extra conditions:
I am looking for the blog and the music player to remain integrated.
I don't want to store my music files remotely.
I don't want to set up a local server.
Perhaps there is a way to add a security exception for my website to my browser, but this seems no longer the case for Firefox.
Any suggestion is most welcome!
I would suggest taking a look at the File System API. It's a very new API that's currently only working with chrome unfortunately :/
What you can basically do is request for access to the local filesystem using window.requestFileSystem() or window.webkitRequestFileSystem(), which has a success callback with a FileSystem object. Using this objects root (a Directory Entry object) you can look up the file using root.getFile(). This has a callback with a FileEntry object. You can then use this file entry to get the actual File object using fileEntry.file() and pass that into a FileReader object to get the data url. Untested example below, probably not perfect and you probably have to tweak with webkit prefixes.
// when file system loads
function onFs(fs){
// locate file
fs.root.getFile('M:/music.mp3', {/*options*/}, function(fileEntry){
// get file / blob
fileEntry.file(function(file) {
// read file
var reader = new FileReader();
reader.onload = function(event) {
var dataUrl = event.target.result;
// create new audio object with data url
// e.g. <audio src="dataUrl" />
};
reader.readAsDataURL(file);
// handle error
} , onError);
// handle error
}, onError);
}
// Opening a file system with temporary storage
window.requestFileSystem(TEMPORARY, 1024*1024 /*1MB*/, onFS, onError);
(I'd like to also mention, I've never used the File System API, but it seems promising)

How can I tell why my website uses LocalStorage and IndexedDb)?

When I visit my website using Google Chrome, Chrome shows (in "Cookies and Site Data") that it's using LocalStorage and IndexedDB. I'm not deliberately doing so, and I'd like to find out why those are appearing in the list.
The site does use a few 3rd-party things, notably (perhaps) Google Universal Analytics and Google Tag Manager, but I checked the JS source for both of those (including the file that gets downloaded on the fly), and could find no obvious references to LocalStorage or IndexedDB (though it's not exactly easy to read the minified code).
Is there any way to tell what's using those features?
FWIW it's an ASP.NET MVC5 website, though I doubt that's relevant.
If you don't have specific code doing this, then third party analytics/ads are the likely culprit. Here's what I'd try:
Use chrome://settings/cookies and delete the storage for your site
Identify a page in your site that causes the data to be written
Modify the page to have an inline script before any other scripts are loaded, that shims the storage APIs with dummy functions like:
window.indexedDB.open = function() {
throw Error('Indexed DB');
};
window.localStorage.setItem = function() {
throw Error('DOM Storage');
};
Reload the page with the developer console open. If you're lucky you'll see exceptions thrown with a stack trace pointing to the code that tried to use those functions.
If not, change those throw lines to simply debugger; to invoke the debugger, and reload the page again. The call stack in the debugger should show you what library is using the storage APIs.

How to Ovverride the backkey button including history of webdav file path

hi i'm creating an app using webdav server.Here i'm getting the response from webdav server and i'm binding it to listbox on clicking on that listbox items each and every item having path in webdav. If i went from main root path to particular folder from there if i click on backkey press event app closing and coming out.I want on backkey press root folder should come which should come from subfolder
Please if anyone knew this help me.I knew how to ovveride but it is closing the app.
Please if anyone help highly appreciable.
protected override void OnBackKeyPress(CancelEventArgs e)
{
startRequest();// it is the method which i can retrieve the file structure.
}
First of all, I suppose you're building a native WP8 app using Silverlight. There're many totally different ways to build apps for WP8 but you haven't specified your platform. If you're using something different ( JS Web / C# Store / C# Xamarin / JS phonegap / C++ XAML / etc ) my answer is irrelevant.
See this answer for one way to handle the hardware back key.
In the handler, you need to check whether the currently displayed folder is the root or not.
If it’s the root or empty, you do nothing just return, let the system handle the event, which will close your app.
If your listbox is showing some non-root folder, you set e.Cancel = true; and show the content of the root WebDAV folder in your listbox. This way the system doesn't handle the back button event so the app doesn't close, but you do handle so you're showing the root folder in your list.

File not found - Laravel - Trying to access private folder

The framework I am using is Laravel 4.2. I have a .json file stored in my /app/database/seeds/json folder, intentionally to stop people from accessing it in my public directory (it's information that I've paid for, and so I don't want people accessing it).
I am trying to access this in a 'typeahead` style feature, but it can never find the file. Currently, the script is:
var location = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: '/app/database/seeds/json/file.json'
});
But in Google inspect, it returns the error:
http://localhost:8888/app/database/seeds/json/file.json 404 (Not Found).
Is there a way of even accessing this file? Or can I use my public file and yet still have some protection on people accessing it?
Any help would be hugely appreciated.
Anything which needs to be publicly accessible, but which comes as part of a package, needs to be published.
Perhaps something like this would get it working:
php artisan asset:publish --path="app/database/seeds/json/file.json" bloodhound/json/file.json
If that worked, the file would be accessible from the URL /packages/bloodhound/json/file.json