133 Commits

Author SHA1 Message Date
Jannis Mattheis
eec23c7d67 fix: panic when write on closed channel 2026-08-21 13:56:28 +02:00
Bernd Konrad
32d240b394 feat: add GOTIFY_OIDC_PROMPT config 2026-08-19 21:04:19 +02:00
Yumechi
5a36c8c42b chore: update go module path to github.com/gotify/server/v3 2026-08-16 17:01:00 +08:00
Bernd Konrad
795d9d1210 feat: disable local auth 2026-08-13 20:47:59 +02:00
Yumechi
75bc19c111 fix: remove panic() and relay password hashing errors to UI 2026-08-06 12:32:23 +08:00
Jannis Mattheis
d09ea4e169 fix: don't drop oidc_id when updating users 2026-07-24 11:01:31 +02:00
Jannis Mattheis
fdf6ce86ea fix: don't include scheme://host inside next 2026-07-16 21:00:37 +02:00
Jannis Mattheis
e2b6a2e828 Merge pull request #992 from gotify/oidc-log
fix: more oidc logging
2026-07-15 17:35:37 +00:00
Jannis Mattheis
bb62086fda fix: more oidc logging
In debug mode this outputs the oidc discovery

    2026-07-07T20:51:14+02:00 DBG discover config={"authorization_endpoint":"http://192.168.178.2:5556/dex/auth","claims_supported":["iss","sub","aud","iat","exp","email","email_verified","locale","name","preferred_username","at_hash"],"code_challenge_methods_supported":["S256","plain"],"device_authorization_endpoint":"http://192.168.178.2:5556/dex/device/code","grant_types_supported":["authorization_code","refresh_token","urn:ietf:params:oauth:grant-type:device_code","urn:ietf:params:oauth:grant-type:token-exchange"],"id_token_signing_alg_values_supported":["RS256"],"introspection_endpoint":"http://192.168.178.2:5556/dex/token/introspect","issuer":"http://192.168.178.2:5556/dex","jwks_uri":"http://192.168.178.2:5556/dex/keys","request_uri_parameter_supported":false,"response_types_supported":["code"],"scopes_supported":["openid","email","groups","profile","offline_access"],"subject_types_supported":["public"],"token_endpoint":"http://192.168.178.2:5556/dex/token","token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"userinfo_endpoint":"http://192.168.178.2:5556/dex/userinfo"} rp.function=NewRelyingPartyOIDC
2026-07-07 20:52:49 +02:00
Jannis Mattheis
509707737a fix: appid spec
It's optional on POST, so not readonly and not required.
2026-07-05 20:36:18 +02:00
Yumechi
5e81bed709 fix(security): check app ownership in security endpoint 2026-07-04 14:45:15 +02:00
Yumechi
52e2b6d764 fixup: go testify style 2026-06-30 19:52:27 +08:00
Yumechi
41cde67072 feat(security): application token refresh 2026-06-30 18:57:12 +08:00
饺子w (Yumechi)
ad977d3d9c feat: EdDSA token for database leakage/index mitigation (#971)
* feat: EdDSA token for database leakage/index mitigation

* [skip ci]: remove token from api output

* fix: e2e tests

* fixup! fix: e2e tests

* doc: document tokens are now optional fields for app and aclient

* fixup(doc): swagger version again

* address review comments

* address review comments
2026-06-28 14:58:20 +00:00
Jannis Mattheis
7a95321bd5 fix: discover oidc signing algs 2026-06-20 15:13:15 +02:00
Jannis Mattheis
bf6d8eee85 fix: map oidc user to iss/sub 2026-06-20 14:07:49 +02:00
Jannis Mattheis
b13080615c fix: default for oidc scopes 2026-06-14 12:32:55 +02:00
Jannis Mattheis
c5fc8b7f8c fix: don't ignore cors requests in dev mode
This will make testing easier, as it's more similar to the actual prod
deployment. We don't have to rewrite anything in vite, as the host and
origin is the same.
2026-06-14 12:32:55 +02:00
Jannis Mattheis
be509766d8 feat: allow sending message with client/basic path 2026-05-25 18:32:05 +02:00
Jannis Mattheis
925fce0bf9 fix: use zerolog 2026-05-20 17:16:35 +02:00
Jannis Mattheis
cf9a1ea32f fix: align session client expiry with cookie max age 2026-05-18 17:16:08 +02:00
Jannis Mattheis
67d87f1b50 feat: clean up expired devices 2026-05-18 17:16:08 +02:00
Jannis Mattheis
4c82768eac test: created at 2026-05-09 22:04:05 +02:00
Jannis Mattheis
cbf5b07c90 feat: add created at to all models 2026-05-09 20:11:06 +02:00
Jannis Mattheis
ef36e7538d fix: /client:elevate to /client/:id/elevate 2026-04-26 12:41:02 +02:00
Jannis Mattheis
a5fc2bcd1d fix: unset elevated until if in the past 2026-04-22 20:10:43 +02:00
Jannis Mattheis
624ab65742 fix: elevate session on login 2026-04-19 19:43:52 +02:00
Jannis Mattheis
a8744482c6 fix: enforce elevated authentication 2026-04-19 19:24:18 +02:00
Jannis Mattheis
c256025b9f fix: return client id and elevatedUntil on /current/user 2026-04-19 19:24:18 +02:00
Jannis Mattheis
58677b32ef fix: add client elevatedUntil 2026-04-19 19:22:31 +02:00
Jannis Mattheis
410571dd18 fix: prevent duplicate requests for apps / clients 2026-04-19 19:22:30 +02:00
Jannis Mattheis
681b9e2d90 fix: unify authentication context
This uses a single struct for the authentication. This prevents further
re-requesting of the already requested data.
2026-04-19 19:22:03 +02:00
Jannis Mattheis
d432900486 fix: logout to /auth/logout and swagger docs
With session elevation, we cannot use DELETE /client as this requires
elevation. It should be possible to logout without an elevated session.

This makes the logout endpoint public api to be used by the android app.
2026-04-19 18:00:16 +02:00
Jannis Mattheis
2674f729eb fix: use decay map 2026-04-11 18:53:48 +02:00
Jannis Mattheis
fb6f90bf59 fix: don't store client name in state 2026-04-11 18:53:48 +02:00
Jannis Mattheis
491325b06f test: oidc tests
It's not easy to test this automatically without a real oidc server.
2026-04-11 18:53:48 +02:00
Jannis Mattheis
6d53859b77 feat: add external oidc flow
Add two new endpoints for native app OIDC authentication using the
PKCE relay pattern (similar to Vaultwarden's SSO implementation):

- POST /auth/oidc/external/authorize - accepts a PKCE code_challenge
from the client, forwards it to the IdP, and returns the authorize URL
- POST /auth/oidc/external/token - accepts the auth code and
code_verifier, relays them to the IdP for token exchange, and returns
a gotify client token

The server never generates its own PKCE pair for this flow. It then relays
the client's code_challenge to the IdP during authorization and the
code_verifier during token exchange. The IdP validates the binding.
Pending auth sessions are stored in memory with a 10-minute TTL.

CSRF protection is provided by the state parameter, which contains a
cryptographically random nonce and is validated on the token exchange.
The state is single-use (deleted from the pending session map on lookup),
preventing replay attacks. Even without single-use enforcement, replay
would be harmless since the IdP's authorization code can only be
exchanged once.
2026-04-11 18:53:48 +02:00
Jannis Mattheis
f130ebe194 fix: add /gotifyconfig endpoint 2026-04-11 18:53:48 +02:00
Jannis Mattheis
cfaddfe255 feat: oidc 2026-04-11 18:53:48 +02:00
Jannis Mattheis
57878e0574 fix: make secure cookie configurable 2026-04-11 18:53:48 +02:00
Jannis Mattheis
50d0572584 feat: implement /auth/local/{login,logout} 2026-04-11 18:53:48 +02:00
Jannis Mattheis
a1f83c5ef8 fix: enforce sort_key is unique per user 2026-01-28 18:46:21 +01:00
Jannis Mattheis
278b873b5b feat: add sort_key to backend 2026-01-24 13:28:40 +01:00
Laurence
883cc15bae fix: hide delete overlay for default app images 2025-11-16 11:27:28 +01:00
Laurence Jones
71e38b9824 Add file type restriction to image upload input using accept attribute (#872)
* Add file type restriction to image upload input using accept attribute

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
Co-authored-by: eternal-flame-AD <yume@yumechi.jp>
2025-11-05 21:03:06 +00:00
饺子w (Yumechi)
496c166981 chore: Migrate github.com/jinzhu/gorm to gorm.io/gorm (#863)
* chore: Migrate github.com/jinzhu/gorm to gorm.io/gorm

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* chore: drop singleton connection limit on sqlite3 backend

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* enhance: database logging

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* Revert "chore: drop singleton connection limit on sqlite3 backend"

This reverts commit b494a3bd1f.

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* typo

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* rename unique_index -> uniqueIndex

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* drop uniqueIndex on primary key

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* migrate fully to new gorm tag format

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* specify unique index name

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* remove pluginConf duplicate index

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* disable auto migrate FK

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
2025-10-29 22:23:10 +00:00
昨夜雨疏风骤
4bc42d2c1d Optimize uniq function for better performance (#852)
Improve the performance of the unique function by:
1. Pre-allocating map capacity with len(s) to avoid frequent map resizing
2. Pre-allocating result slice capacity with len(s) to reduce append overhead
3. Reducing the number of traversals performs well under the condition of a large number of elements

These changes maintain the original behavior (preserving element order) 
while reducing memory allocation operations, especially effective for 
large slices (100k+ elements) with benchmark showing ~25% speedup.

No breaking changes, the function signature and output order remain unchanged.
2025-10-03 01:17:47 +00:00
renovate[bot]
a0bad7bd5a chore(deps): update bump go dependencies (#751)
* chore(deps): update bump go dependencies

* Update golangci-lint

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* Update golangci config to reflect new format

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* remove deprecated ioutil package

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: eternal-flame-AD <yume@yumechi.jp>
2025-01-17 05:51:08 +00:00
renovate[bot]
60bafd2b98 chore(deps): update module gopkg.in/yaml.v2 to v3 (#719)
* chore(deps): update module gopkg.in/yaml.v2 to v3

* fixup! chore(deps): update module gopkg.in/yaml.v2 to v3

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: eternal-flame-AD <yume@yumechi.jp>
2024-11-07 17:34:22 -06:00
Eng Zer Jun
0bfa5ca4d9 perf: avoid allocations with (*regexp.Regexp).MatchString (#604)
We should use `(*regexp.Regexp).MatchString` instead of
`(*regexp.Regexp).Match([]byte(...))` when matching string to avoid
unnecessary `[]byte` conversions and reduce allocations.

Example benchmark:

var allowedOrigin = regexp.MustCompile(".*.example.com")

func BenchmarkMatch(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if match := allowedOrigin.Match([]byte("www.example.com")); !match {
			b.Fail()
		}
	}
}

func BenchmarkMatchString(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if match := allowedOrigin.MatchString("wwww.example.com"); !match {
			b.Fail()
		}
	}
}

goos: linux
goarch: amd64
pkg: github.com/gotify/server/v2/api/stream
cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
BenchmarkMatch-16          	 2076819	       647.7 ns/op	      16 B/op	       1 allocs/op
BenchmarkMatchString-16    	 2536326	       442.0 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/gotify/server/v2/api/stream	3.552s

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2023-10-23 15:57:15 +00:00