Repository: platers/obsidian-linter (ts)

Issue:
Bug: No Bare URLs fails if url contains '@' (at)
- [x] I have verified that I am on the latest version of the Linter

## Describe the Bug

URLs with an '@' symbol in the path are not enclosed completely

## How to Reproduce

Steps to reproduce the behavior:

1. Enable `No Bare URLs` in plugin settings
2. Disable `No Bare URIs` in plugin settings
3. Create a new note
4. Insert `https://domain.org/@user/long-kebab-case-path`
5. Execute command `Lint the current file`
6. The link is not fully enclosed

Or

Example to reproduce issue with

``` markdown
https://domain.org/@user/long-kebab-case-path
```

## Expected Behavior

The full link should be enclosed by angle brackets `<link>`.

Expected output if applicable:

``` markdown
<https://domain.org/@user/long-kebab-case-path>
```

## Actual Behavior

Only a part is enclosed with angle brackets.

Actual output if applicable:

``` markdown
<https://domain.org/>@user/long-kebab-case-path
```

## Screenshots

\-

## Device

- [x] Desktop
- [x] Mobile

## Additional Context

I will provide a PR asap.

Pull request:
Fix: Fix URL regex to allow '@' in the path
Closes #1050.

Patch:
diff --git a/src/utils/regex.ts b/src/utils/regex.ts
index ebc5fcb..1059ba4 100644
--- a/src/utils/regex.ts
+++ b/src/utils/regex.ts
@@ -26,7 +26,7 @@ export const tableRow = /[^\n]*?\|[^\n]*?(\n|$)/m;
 // based on https://gist.github.com/skeller88/5eb73dc0090d4ff1249a
 export const simpleURIRegex = /(([a-z\-0-9]+:)\/{2,3})([^\s/?#]*[^\s")'.?!/]|[/])?(([/?#][^\s")']*[^\s")'.?!])|[/])?/gi;
 // generated from https://github.com/spamscanner/url-regex-safe using strict: true, returnString: true, and re2: false as options
-export const urlRegex = /(?:(?:(?:[a-z]+:)?\/\/)|www\.)(?:localhost|(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?|(?:(?:[a-z0-9][-_]*)*[a-z0-9]+)(?:\.(?:[a-z0-9]-*)*[a-z0-9]+)*(?:\.(?:[a-z]{2,})))(?::\d{2,5})?(?:(?:[/?#][a-z0-9-_%/&=?$.+!*‘(,#]*[a-z0-9-%_/$+!*‘(,])|[/])?/gi;
+export const urlRegex = /(?:(?:(?:[a-z]+:)?\/\/)|www\.)(?:localhost|(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?|(?:(?:[a-z0-9][-_]*)*[a-z0-9]+)(?:\.(?:[a-z0-9]-*)*[a-z0-9]+)*(?:\.(?:[a-z]{2,})))(?::\d{2,5})?(?:(?:[/?#][a-z0-9-_%/&=?$.+!*‘(,#@]*[a-z0-9-%_/$+!*‘(,])|[/])?/gi;
 export const anchorTagRegex = /<a[\s]+([^>]+)>((?:.(?!<\/a>))*.)<\/a>/g;
 export const wordRegex = /[\p{L}\p{N}\p{Pc}\p{M}\-'’`]+/gu;
 // regex from https://stackoverflow.com/a/26128757/8353749


Test patch:
diff --git a/__tests__/no-bare-urls.test.ts b/__tests__/no-bare-urls.test.ts
index f0acb67..f60e4fd 100644
--- a/__tests__/no-bare-urls.test.ts
+++ b/__tests__/no-bare-urls.test.ts
@@ -193,6 +193,30 @@ ruleTest({
         noBareURIs: true,
       },
     },
+    {// accounts for https://github.com/platers/obsidian-linter/issues/1050
+      testName: 'Make sure that URls containing an \'@\' are properly matched',
+      before: dedent`
+        https://domain.org/@user
+        https://domain.org/@user/some-kebab-case-path
+        https://domain.org/some-path/@user/some-kebab-case-path
+        https://domain.org/some-path/@user/some-kebab-case-path
+        https://domain.org/some-path/@user/some-kebab-case-path/@user
+        https://domain.org/some-path/@user/some-kebab-case-path#anchor
+        https://domain.org/some-path/@user/some-kebab-case-path#anchor?t=4
+      `,
+      after: dedent`
+        <https://domain.org/@user>
+        <https://domain.org/@user/some-kebab-case-path>
+        <https://domain.org/some-path/@user/some-kebab-case-path>
+        <https://domain.org/some-path/@user/some-kebab-case-path>
+        <https://domain.org/some-path/@user/some-kebab-case-path/@user>
+        <https://domain.org/some-path/@user/some-kebab-case-path#anchor>
+        <https://domain.org/some-path/@user/some-kebab-case-path#anchor?t=4>
+      `,
+      options: {
+        noBareURIs: false,
+      },
+    },
   ],
 });