nightscout / Trio

MIT License
49 stars 154 forks source link

Auto-remove trailing slash from Nightscout URL #190

Closed LiroyvH closed 1 month ago

LiroyvH commented 2 months ago

When users enter a trailing / in their Nightscout URL (Eg: "https://url.night.scout/" rather than "https://url.night.scout"), this will immediately result in a "Not found!" (404) error, because a / is already being appended. (Resulting in "https://url.night.scout//" being requested from the NS-server).

This check removes the trailing slash when the user enters it in to the URL field, to prevent 404's.

MikePlante1 commented 2 months ago

Thanks!

@bjorkert recently added some URL sanitization to Loop Follow. Posting that PR here for inspiration: https://github.com/loopandlearn/LoopFollow/pull/286

LiroyvH commented 2 months ago

Ok - I made changes to the code to not only remove the trailing / but also do the same checks Jonas added (symbols, capital letters, etc.) to LoopFollow. Should be force pushed thanks to @MikePlante1. Better? :)

marionbarker commented 2 months ago

I failed to test that LoopFollow PR well enough. I discovered this while testing a later PR. I don't know if your implementation has the same problem.

"Try typing in https://sitename/, instead of pasting in a URL, and you'll notice it won't allow you to enter the / characters."

@bjorkert made an additional change, please see this commit:

LiroyvH commented 2 months ago

@marionbarker I'm not sure I understand the problem or I cannot reproduce it. :) When I enter https://sitename/ in to the URL-field, I can continue to modify it however I wish.

Maybe a difference, but I haven't looked at how LoopFollow does it, is that in this instance within Trio the checks are not ran until you actually tap "Connect" - so when you're supposedly finished entering the URL. If LoopFollow does it on the fly (whilst it is still being entered), maybe that is a difference? Just something that sprang to mind, but either way: I don't think I can reproduce that particular problem you mention. :)

-edit- Even if I enter https://sitename/ and press "Connect": it just removes the trailing slash and nothing weird happens. (Of course it errors out with a DNS lookup failure, but that's expected haha. :))

marionbarker commented 2 months ago

I was not sure, looking at your implementation, whether you would have the same problem.

Thanks for checking.

bjorkert commented 2 months ago

LoopFollow does cleaning on each detected change, so it did drop "/" when you are enter https:/, while paste worked fine. If you trigger this using a manual "Connect" button you would be ok.

MikePlante1 commented 2 months ago

In testing this, I found out that without this PR, a valid token will actually allow it to connect to a Nightscout, even though it won't actually let it download or upload anything from that Nightscout without an API Secret. If the correct API Secret is entered, though, a URL with a token at the end allows Trio to upload and download to Nightscout successfully, even if the token is invalid.

This makes me think I was wrong for suggesting sanitization of the URL, since if someone copies their NS with a token attached and doesn't bother to delete their token, but also adds their API Secret, that would currently work fine in dev now. But after this PR, it would turn the query parameters into a path and cause an error. So maybe it's best to revert to your original commit of only deleting a trailing /. Sorry. 😅

I also found that my Nightscout works just fine in dev (without this PR) with a trailing /, but maybe that's just FreeDNS or Google Cloud fixing it on their end.

LiroyvH commented 2 months ago

@MikePlante1 So you want me to force push the previously force pushed away code huh :P Alright, I'll try to do that tomorrow. :)

bjornoleh commented 2 months ago

Regarding @MikePlante1 ‘s comment, I think @bjorkert made some changes to LF to allow a url with token to be pasted without the API secret. Perhaps we could port that as well?

LiroyvH commented 2 months ago

Alright, I've just reverted the commit back to the original that just checks for the trailing /. I think in general that's likely enough anyway as typically a.) capital letters are no problem for DNS resolution, b.) users will not quickly enter other symbols in their URL. When they do: they'll get a connection failure and can probably spot the error. The trailing / being an issue is just an obscure problem that may not be so easily understood.

If we do want to do something else/more to the URL-field check, let me know and I can make another commit/PR. :P For now, let's just push this one for the trailing / issue and start with fixing that :D

sonarcloud[bot] commented 2 months ago

Quality Gate Passed Quality Gate passed

Issues
1 New issue
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

bjornoleh commented 1 month ago

The patch works as expected, as tested by adding a trailing /, which is removed upon tappingConnect`. Thanks!

However, Xcode wanted to change some indentation upon build, and presented the following diff for L52-L55 of NightscoutConfigStateModel.swift:

           if let CheckURL = url.last, CheckURL == "/" {
-                  let fixedURL = url.dropLast()
-                  url = String(fixedURL)
-              }        
+            if let CheckURL = url.last, CheckURL == "/" {
+                let fixedURL = url.dropLast()
+                url = String(fixedURL)
+            }

You probably want to build and then commit or amend those changes.

I made a PR to the pull request branch to fix my change request: https://github.com/LiroyvH/Trio/pull/1

I will approve when this is merged :-)

dnzxy commented 1 month ago

@LiroyvH what is your status on merging @bjornoleh 's PR to your feature branch so this can move forward here?

LiroyvH commented 1 month ago

@dnzxy Haven't had the time to look at it, probably somewhere this week (hopefully today)

LiroyvH commented 1 month ago

@dnzxy I suppose this is fixed now

dnzxy commented 1 month ago

Hi, I‘d like to propose a more elegant solution that

func isValidURL(_ urlString: String) -> Bool {
    let pattern = "^(http|https)://[^\\s/$.?#].[^\\s]*$"
    let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
    let range = NSRange(location: 0, length: urlString.utf16.count)
    return regex.firstMatch(in: urlString, options: [], range: range) != nil
}

func reformatURL(_ url: String) -> String {
    var formattedURL = url
    if isValidURL(formattedURL) {
        if let lastSlashRange = formattedURL.range(of: "/", options: .backwards) {
            formattedURL = String(formattedURL[..<lastSlashRange.upperBound])
            formattedURL.removeLast()
        }
    }
    return formattedURL
}

Example usage:

var url = "https://www.my-example.com/some/path/?foobar=baz"
url = reformatURL(url)
print(url)  // Output: "https://www.my-example.com/some/path"

Used to guard URL entering via


if isValidURL(url) { 
   url = reformatURL(url)
   // …
} 
dnzxy commented 1 month ago

@LiroyvH and reviewers (@bjornoleh, @MikePlante1 , @marionbarker ) – how's this one looking? Will the comment be addressed? Is it necessary to be addressed?

bjornoleh commented 1 month ago

@LiroyvH and reviewers (@bjornoleh, @MikePlante1 , @marionbarker ) – how's this one looking? Will the comment be addressed? Is it necessary to be addressed?

Maybe you could make a PR with the suggested changes to the PR branch, or as a separate PR to dev/alpha?

The current PR is ok, but could of course be improved.

dnzxy commented 1 month ago

I disagree in that this current PR is okay because it’s lacking validation if the entered URL is a valid URL. I‘m okay with keeping the logic to only remove trailing /.

bjornoleh commented 1 month ago

@marionbarker , without the fix, I am finding that connection is blocked with one or several trailing slashes, with the message "Error: Not Found"

Branch: current dev aeb4ee1e048a790f93e2d84c28955d6993e847f6

bjornoleh commented 1 month ago

@LiroyvH , please sync your PR branch with dev, as a breaking change for Omnipod just landed in dev. Thanks!

LiroyvH commented 1 month ago

@bjornoleh Yeah I don't know if that worked out. I did a sync on there and it resulted in adding an extra commit to this PR...? I don't think that's right? Pls let me know.

@marionbarker Some of the nightscout providers ignore extra slashes on their end, such as yours by the sounds of what you're writing. That's great, but not the target for this fix. :) This fix is for the ones that don't, which typically includes self-hosted solutions. If you add ten /'s to the end: yes, this PR doesn't fix that - this is just a fix for the uttermost common occurrence: one / at the end of an URL, which is a very normal thing to happen but can lead to errors and thus this PR ensures its stripped. Nothing more, nothing less. (And if someone doesn't notice ten slashes at the end, I think we have bigger issues. :P) I'm sure we can enhance this and add more checks and balances to the URL sanity check (note: must be checked that it doesn't break in-URL variables!); but as long as there are no PR's for that I'd suggest doing the obvious: at least merge this first, we can look at doing more later.

Otherwise indeed please just close this PR so no more time is spent on it. It's an extremely simple fix to an extremely often occurring URL-notation and I'm a wee bit surprised there's so much discussion over 4 lines of extensively tested code for a simple URL enhancement. Let's make a choice now to merge it or decline it.

bjornoleh commented 1 month ago

The merge of dev into your branch was good! :-)

dnzxy commented 1 month ago

I'm a wee bit surprised there's so much discussion over 4 lines of extensively tested code for a simple URL enhancement.

I made a proposition to enhance your work to which you don’t really have reacted so far. If you don’t intend to incorporate the suggestion, that’s okay; ignoring it but then demanding a PR to be either merged now or closed, is not really a nice way of going about it, especially with different tester feedback by Marion.

I tested the as-is PR and it works on my end, I‘m fine with either way. Since Liroy took the time out of his day to propose this PR, I deemed it a good opportunity to at least add a URL validity check. It’s okay if that doesn’t go in, we can improve input validation another day 😊

marionbarker commented 1 month ago

I tested only with Nightscout created using the Google Cloud which evidently does not care if there are final slashes. @bjornoleh got different results from me and @LiroyvH explained why. I will edit my original comment. This PR does indeed remove the final slash and if that makes it easier for people to paste in the URL, that's fine with me.