Closes DEVEX-604
Hardens `redirect` URL handling in the OAuth2/OIDC/external-auth
callback flows so redirects are always reduced to a safe, relative path
local to the application. Previously a redirect value with an opaque
scheme (e.g. `javascript:...`) or a path with multiple leading slashes
(e.g. `///evil.com`) could survive sanitization mostly intact.
Also de-duplicates the previously copy-pasted `uriFromURL` helper (now
exported `httpmw.URIFromURL`) so there's a single implementation shared
by `coderd/userauth.go`, `coderd/externalauth.go`, and
`coderd/httpmw/oauth2.go`.
<details>
<summary>Context</summary>
Addresses a low-severity finding reported via a pentest disclosure: the
redirect sanitizer used `url.Parse(...).RequestURI()`, which doesn't
reject non-hierarchical (opaque) URLs and doesn't collapse extra leading
slashes, so crafted `redirect` values could partially survive
sanitization.
</details>
This PR was authored by a Coder Agent on behalf of @aslilac.
**Breaking Change:** Existing oauth apps might now use PKCE. If an
unknown IdP type was being used, and it does not support PKCE, it will
break.
To fix, set the PKCE methods on the external auth to `none`
```
export CODER_EXTERNAL_AUTH_1_PKCE_METHODS=none
```
Solves #15575
Adds OAuth access token revocation when unlinking external auth
provider. Due to revocation not being consistently implemented by
providers this is only best effort attempt. Unsuccessful revocation
won't influence link removal.
* feat: add endpoints to list all authed external apps
Listing the apps allows users to auth to external apps without going through the create workspace flow.
* feat: allow external services to be authable
* Refactor external auth config structure for defaults
* Add support for new config properties
* Change the name of external auth
* Move externalauth -> external-auth
* Run gen
* Fix tests
* Fix MW tests
* Fix git auth redirect
* Fix lint
* Fix name
* Allow any ID
* Fix invalid type test
* Fix e2e tests
* Fix comments
* Fix colors
* Allow accepting any type as string
* Run gen
* Fix href
* chore: move `/gitauth` to `/externalauth` on the frontend
This actually took a lot more jank than anticipated,
so I wanted to split this up before adding the ability
to embed new providers.
* Rename FE
* Fix em' up
* Fix linting error
* Fix e2e tests
* chore: update helm golden files