-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@uppy/companion,@uppy/companion-client: pass query params along more consistently #4551
Conversation
1da5c7d
to
03520ba
Compare
This allows to define dynamic properties for grant providers. E.g. `[subdomain]` can be automatically replaced in `authorize_url` and `access_url`. For that to work we need to include the dynamic property in the redirect to the grant middleware. We merge the grantConfig back to the providerConfig, so we can determine the required query params based on the `dynamic` property. This avoids an attacker overriding unexpected properties (if we simply serialize and pass along `query`)
03520ba
to
968fe8a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure about this one. why do we need the possibility to pass dynamic query parameters from the client to logout
and thumbnail
? e.g. why does a custom form need to pass a query parameter to logout and thumnail?
res.redirect(req.companion.buildURL(`/connect/${req.companion.provider.authProvider}?state=${state}`, true)) | ||
const providerName = req.companion.provider.authProvider | ||
const qs = queryString(Object.fromEntries( | ||
req.companion.options.providerOptions[providerName]?.dynamic?.map(p => [p, req.query[p]]) || [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure about this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -73,6 +73,7 @@ module.exports.app = (optionsArg = {}) => { | |||
const providers = providerManager.getDefaultProviders() | |||
|
|||
providerManager.addProviderOptions(options, grantConfig) | |||
options.providerOptions = merge(options.providerOptions, grantConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure about this change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is here because grant
does interpolation for certain settings passed as GET parameters to the connect handler if they are marked as dynamic, e.g. if you add subdomain to the dynamic array, you can use it in authorize_url and access_url (c.f. https://github.com/simov/grant#dynamic-http and https://github.com/owncloud/uppy/blob/3403194fd4692c679e03d993c040c6d8ac5ac29a/packages/%40uppy/companion/src/config/grant.js#L47-L57 - yes, it should only be used as a subdomain not as a fqdn but that's a dlfferent topic).
To make this work in companion we need to forward the dynamic paramaters in the redirect from our connect handler to the grant connect handler.
In order to achieve that, I merge the grant config including the dynamic option back to providerOptions and loop over the dynamic
array in our connect handler (which is the other part of the code you commented on)
edit: fixed link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
subdomain is passed to every request as query so we can use it there.
I use it in my WebdavProvider to specify the server url - so I also need it in logout and thumbnail functions and everything else that potentially interacts with the server edit: not yet implemented, but when I want to, I need access to the server url/domain |
Sorry for the delays. We've had some discussions and we're still open to supporting WebDAV, but we need to find an abstraction that is secure and works well for multiple other use cases such as FTP too. I will do some prototyping. |
Feel free to take as much or as little inspiration as you want from owncloud#1 which is the current state of our integration Ftr this was the hardest to figure out to make a login work: |
Thanks, I will! I see that owncloud#1 main needs to be updated to upstream main, because we merged alot of your PRs here.
ah yes. Initially I was a bit confused because I thought what you wanted to add support for is a simple webdav public URL without any authentication. but I realised that you want to add two different providers:
I think it would also make sense to support public webdav urls with |
Yep, indeed, I plan to update it in a bit. but to not overcomplicate things, I would suggest to iterate and handle links without password or/and oauth authenticated links first |
Rebased |
Created a new PR #4619 as an alternative to this PR, for accommodating providers with different auth flows (non-oauth), as well as per-provider state and OAuth dynamic parameters. After it has been reviewed, I think owncloud#1 can be adapted to match #4621 |
As said elsewhere: I'm not attached to my specific implementation, if we go for your approach and that solves my use case, I'm more than happy 👍️ |
This PR is the first in a series of changes I would like to upstream.
The big picture is: I have implemented imports from Nextcloud/ownCloud based WebDAV servers.
They can be self hosted and so users need to provide a URL before they can login - which requires changes in companion and the Dashboard/ProviderView so it can be reasonably implemented.
The current state of the complete implementation can be seen here: dschmidt#1
I think submitting it in total will be very hard to review, so I'm going to send a bunch of small scoped PRs.
query
is passed toprovider.list
,provider.size
andprovider.download
already - this PRs adds it toprovider.logout
andprovider.thumbnail
invocations.Moreover, it adds a
customQueryParams
property to providers in the ui which is automatically serialized and appended to requests to those endpoints.This makes it possible to implement custom forms. (see #4555)