Accessing GraphiQL over a JWT protected route in ExpressJS - express

So far I've always had one big painpoint with GraphQL.
I'm very well aware that you can specify headerEditorEnabled when you setup express-graphql like this:
graphiql: { headerEditorEnabled: true, },
However, that doesn't really help if you've protected the /graphql route to begin with.
As far as I'm aware, you'll need to validate the access token before you define the context, to be able to put the user (if successful) inside the context so it is easily available in the resolvers.
I only found 1 resource adressing this issue: https://medium.com/codelit/accessing-graphiql-over-a-jwt-protected-route-in-expressjs-b2f4de6c7dd8 and I don't particularly like the solution of installing the modheader chrome extension, as it will messup other websites if you forget to enable it. Also it seems like a hacky workaround.
So I'm curious what other alternatives there might be to get graphiql working in such a scenario. So far I'm just using postman, which is equally as good for specifying the query, however it does lack the ability to browse through the schema, so getting graphiql to work would be best, if possible :-)

Related

LinkedIn API Changes

Our LinkedIn API calls started failing. Even the simplest /v1/prople/~ calls started erroring with This resource is no longer available under v1 APIs.
So we're trying to migrate stuff using the new /v2 way, but somehow it seems not to be working. For example (and after requesting a token with the new scopes), a simple request to /v2/me fails to return the fields we need (amongst others, headline and location). When asking explicitly for these fields, we're told that we don't have access to them - even tho the token was generated using the r_basicprofile r_liteprofile r_emailaddress scopes.
We've tried numerous combinations and variations of asking for certain fields, projections, formats, etc from the Microsoft docs - with no avail and we're wondering whether the /v2 API is actually something functional - is there anyone successful using it, and if so, how?
A sample CURL request with an obfuscated Bearer would be a good way for us to understand what we're doing wrong - but it seems that even the simplest requests verbatim from the docs just fail.
EDIT: After some research, it looks like Microsoft changed their versioned API behavior without being consistent in the docs. Some docs point to r_liteprofile and some others to r_basicprofile as the default way to go now without being "Linkedin Partners". We were previously requesting r_emailaddress too and the headline and location parts of the r_basicprofile bits were used in our code in many different places.
These were two problems:
Some of the fields are removed from v1 (headline, email, location etc),
Most of the fields requested are not available in v2 without special scopes, but these scopes are very poorly documented as being part of a "LinkedIn Partner" program our app has to be accepted in before we can now use them.
The basic answer to this question is that LinkedIn (Microsoft) made backward-incompatible changes to their API.

In IdentityServer4, how do you securely store the ReturnUrl?

I am developing an identity server 4 dotnet core application so this is as much as a dotnet question than and IDS4 question. One example of state I need to maintain between pages (login, signup etc...) is the returnUrl. The application I'm migrating from used to store it in a session variable but, as I understand, unless I run a persistent session strategy, this won't scale well.
So currently, I'm passing it around as a field in each View Model used by each view so it can be returned. Is this a sound approach? I'll be needing other fields to be passed around as well so I'm wondering whether this is a secure and logical way to do it.
So currently, I'm passing it around as a field in each View Model used by each view so it can be returned. Is this a sound approach?
Yes, how you choose to pass it around is up to you, I choose this same approach. You could use TempData, Sessions or even localStorage as an alternative. I think having it in the models (view models) is a good approach because you are explicitly specifying where you want the return url to exist, otherwise it might persist in context that you wouldn't want.
Now the security question because obviously you might be able to see the return url in the browser address field.
As part of Identity Server 4 setup you specify which return url's you are allowed to redirect back to, so I don't think there is any harm in having the users see the redirect url.
Something to consider is what if the user would share the url to someone else in the middle of the authentication process, would they be able to resume from that part of the process that the initial user has stopped? is this something you want in your app?
If you mean reliably instead of securely, write tests which will provide you with confidence that your code works.

Pwa wrong to consider api cache instead of db?

im building a specific book reader like app.
Main page call api/booksList and receive the json array containing each book info like:
[ { id: server_db_id, title: "title test", sum: 10 , date: ... }
]
ans its cached after the request, so im not saving the book list into indexedDB, localStorage or other storage. If i need one specific book, i just call the api book list again and filter it. Is that bad design? (book will be over 200 items)
Whe user open the book, it call the /api/book/book_id and its cached too, the opened book response is a json list of the lines of the book, eg:
[
{
id: ...
content: "This is line...lore ipsum..."
....
}
]
I put the api response inside vue data variable and the component is rendered correclty
Im not using any kind of handler for keeping this offline by my hand. To detect if user already opened this book, i just call the api, check if errors happened or the responde body has content.
Is that a wrong, bad or stupid decision? Will this hit the quota limit api or other kind of limitation? The "gods" of pwa will raise the finger to me and say: WAAAT. (im not using indexedDB at first because it need some models handling and i want to make things easier if possible)
I my self was just researching this and concluded, at the moment I am going to go with this method, where I use cache for assets, js, css, html etc based on their matching routes.
Then when it comes to data e.g. json requests etc. Its best to store them in indexedDB (or an equivalent), which really does not require a model or schema as such.
See Jake Archibald's IndexedDB-Promise library https://github.com/jakearchibald/idb its really simple to get your head round.
Though both Jake and Addy say it's not a defacto rule, so you can decide ultimately what is best for you.
Read this for better clarification
https://developers.google.com/web/ilt/pwa/live-data-in-the-service-worker
https://medium.com/dev-channel/offline-storage-for-progressive-web-apps-70d52695513c
It helped me to make a better decision on how to go about moving forward.
Recommendations Also
Check out PWA Training: https://developers.google.com/web/ilt/pwa
Workbox: https://developers.google.com/web/tools/workbox (This has sped up my development massively!)
Codelabs: https://codelabs.developers.google.com/ (Search PWA)
The guides on here are really good at taking you through everything you need.
Good Luck with your PWA
Random thought (edit)
One thing that makes me question this though is based on some of the examples and guides I have seen is that, data storage is handled in a more ad-hoc manner. For example, if the PWA calls out an API, there are two methods I have come across where you can either manage cached data in the application or in the service worker, e.g. if your API calls to get JSON fails in the app, it can revert to getting data in the indexedDB which hopefully was pre-cached the first time your app called the API.
Or you can use self.addEventListener('fetch', (event) => { ad-hoc stuff here }) this is where you can match either an asset, or data request and hijack the response with either a cache or indexedDB response. Which prevents the need handle offline data in your app.
The first method makes me feel uneasy so i'm gonna go with the addEventListener approach both in the service worker cause thats what it is there for plus my app does not then have to worry about that.

Meteor File Uploads

I see that this has been asked here before, but nothing since Meteor.http has been available. I'm still grasping the concepts of Meteor and file uploads are totally eluding me.
Here's my question:
So, in what I believe to be the right method,
Meteor.http.call("POST", url, [options], [asyncCallback]) what do you put for the url? With the client/server javascript relationship in meteor, it doesn't seem like it really uses urls that much.
If anyone has a basic example of a file upload in meteor, that would just be extra awesome.
well been playing a bit with meteor. Made a collectionFS a mix of meteor and gridFS (could be compatible).
Test it here: http://collectionfs.meteor.com/
It support quit large files, multiple files, users etc. I've tested a 50Mb seems ok, if connection is lost or browser dies the user can resume upload.
It should even be possible to have multiple users upload to exact same file - haven't quit found a usecase for it, but it's possible.
Accounts, publishing etc. is as with collections - the test is in autopublish mode, though only meta data is avaliable - chunks of data is served in background via blobs.
I'll try getting it on github,
Take a look at filepicker.io. They handle the upload, store it into your S3, and return to you the url that you can dump into your db.
Wget the filepicker script into your client folder.
wget https://api.filepicker.io/v0/filepicker.js
Insert a filepicker input tag
<input type="filepicker" id="attachment">
In the startup, initialize it:
Meteor.startup( function() {
filepicker.setKey("YOUR FILEPICKER API KEY");
filepicker.constructWidget(document.getElementById('attachment'));
});
Attach a event handler
Template.templateNameHere.events({
'change #attachment': function(evt){
console.log(evt.files);
}
});
(I had posted on How would one handle a file upload with Meteor? Sorry. I'm new here. Is it kosher to copy the same answer twice? Anyone who knows better can feel free to edit this.)
Checkout how to accomplish this using Meteor.Method on the server and the FileReader's api on the client
https://gist.github.com/dariocravero/3922137
After several searches, this looks to me the easiest (and for the moment the meteor's style way) to handle a file upload with no extra dependencies.
Since meteor includes JQuery by default, you can utilize a Jquery plugin for that, i presume, something like: https://github.com/blueimp/jQuery-File-Upload/wiki/Options can do the trick for you, and supports both GET and PUT.
Otherwise it would be a pain in the ass to get it to work, but not impossible, since you can access PUT in meteor.
If you would prefer a more pure JS sollution maybe you can look at: http://igstan.ro/posts/2009-01-11-ajax-file-upload-with-pure-javascript.html
And adapt it.
There is no ready made support for file uploads so share what you come up with, i would be very interested!
Alternatively (if you wouldn't like to use a 3rd party solution like filepicker) you could use the meteor router package.
This handles the HTTP requests on server-side.

Multiple Auth in Yesod?

I need to require multiple authentication types in my app; in particular: some parts of the app require authentication to dropbox, and some parts require email-based authentication such as browserID.
How can I handle this?
Can I attach authentication to a subsite? Since the YesodAuth class takes the master foundation data type as its argument in all the examples, it's not obvious how I can do that.
If not, is there some other way?
Apologies if my answer is a tad vague (it's been a few months since I've used Yesod, and the dev cycle is quite rapid), but if I remember correctly you can specify multiple varieties of authentication within the YesodAuth class (browserID, google etc), in which case the user would be provided with the option as to which to use at each authentication request. Something like:
authPlugins _ =
[ authBrowserId
, authGoogleEmail
]
etc.
Whether or not you can explicitly set one auth type for each circumstance I do not know I'm afraid, and whether or not this solves your problem I'm unsure.