37 Commits

Author SHA1 Message Date
kolaente
7c7e060d16 feat(auth): include is_admin in JWT claims 2026-04-20 18:55:06 +00:00
MidoriKurage
fb0d0cb32c fix(auth): Cleanup getRefreshTokenCookiePath implementation 2026-04-20 14:26:49 +00:00
MidoriKurage
c027d7ef40 fix(auth): Make refresh token path respect to public URL 2026-04-20 14:26:49 +00:00
kolaente
e025209e3c fix(security): validate link share JWTs against DB on every request
Previously GetLinkShareFromClaims built a *LinkSharing entirely from JWT
claims with no DB interaction, so deleted shares and permission downgrades
took up to 72h (the JWT TTL) to take effect. The permission and sharedByID
claims were trusted blindly.

GetLinkShareFromClaims now takes an *xorm.Session, looks up the share via
GetLinkShareByID, verifies the hash claim against the DB row, and returns
ErrLinkShareTokenInvalid when the row is missing or the hash mismatches.
The permission and sharedByID claims are discarded; the DB row is
authoritative. GetAuthFromClaims opens a read session for the link-share
branch, mirroring the existing API-token branch.

Token creation and the JWT format are unchanged, so already-issued tokens
keep working except when the underlying share has been deleted or its hash
no longer matches.

Fixes GHSA-96q5-xm3p-7m84 / CVE-2026-35594.
2026-04-09 15:38:07 +00:00
kolaente
55ea5bd966 refactor(auth): extract shared token validation into auth package
Move JWT parsing (GetUserIDFromToken) and API token validation
(ValidateAPITokenString) into pkg/modules/auth so both HTTP middleware
and WebSocket auth use the same logic. This ensures consistent token
validity checks including expiry and user status (disabled/locked).

The HTTP API token middleware now delegates to the shared function,
removing duplicated lookup/expiry logic.
2026-04-02 16:30:23 +00:00
kolaente
83bac15841 feat: rename ServiceJWTSecret to ServiceSecret with deprecation (#2502) 2026-03-30 12:07:01 +02:00
kolaente
7a258f67c7 refactor: extract shared RefreshSession helper
The cookie-based /user/token/refresh handler had session refresh logic
(lookup, expiry check, token rotation, user fetch, JWT generation)
that will be reused by the OAuth token endpoint. Extract it into
auth.RefreshSession() and rewrite RefreshToken to use it.
2026-03-27 23:05:04 +00:00
kolaente
530973c475 fix(auth): make SameSite=None conditional on HTTPS for refresh cookie
SameSite=None requires Secure=true per browser spec. When running over
plain HTTP (local dev, e2e tests), browsers reject or downgrade the
cookie, breaking session refresh. Fall back to SameSite=Lax for HTTP
while keeping SameSite=None for HTTPS (needed for the Electron desktop
app cross-origin scenario).
2026-03-03 10:41:19 +01:00
kolaente
28f98a7a96 fix(auth): use SameSite=None for refresh token cookie to fix desktop app
SameSite=Strict prevents the browser from sending the HttpOnly refresh
token cookie in cross-origin contexts like the Electron desktop app,
where the page runs on localhost but the API is on a remote host. This
caused sessions to expire quickly because refresh requests never
included the cookie.

SameSite=None allows cross-origin sending while HttpOnly still prevents
JavaScript from reading the cookie value (XSS protection).

Resolves #2309
2026-03-02 13:54:10 +01:00
kolaente
f3ac0574c0 fix(auth): use checked type assertions for all JWT claims 2026-02-25 13:01:00 +01:00
kolaente
764d3569ce fix: close leaked database sessions
Add defer s.Close() to sessions that were never closed:
- auth.GetAuthFromClaims inline session
- models.deleteUsers cron function
- notifications.notify database insert
2026-02-25 11:03:02 +01:00
kolaente
8ee069a2a3 feat: add session-based auth with refresh token rotation
- Login creates a server-side session and sets an HttpOnly refresh
  token cookie alongside the short-lived JWT
- POST /user/token/refresh exchanges the cookie for a new JWT and
  rotates the refresh token atomically
- POST /user/logout destroys the session and clears the cookie
- POST /user/token restricted to link share tokens only
- Session list (GET) and delete (DELETE) routes for /user/sessions
- All user sessions invalidated on password change and reset
- CORS configured to allow credentials for cross-origin cookies
- JWT 401 responses use structured error code 11 for client detection
- Refresh token cookie name constants annotated for gosec G101
2026-02-25 10:30:25 +01:00
kolaente
e90cb2631d fix(auth): remove unnecessary fields from JWT token payloads
Remove email, name, emailRemindersEnabled, and isLocalUser from user JWT
claims, and isLocalUser from link share JWT claims. These fields are never
used from the token - the backend always fetches the full user from the
database by ID, and the frontend fetches user data from the /user API
endpoint immediately after login.

Also simplify GetUserFromClaims to only extract id and username, and
remove the now-unnecessary email override in the frontend's
refreshUserInfo.
2026-02-08 21:30:07 +01:00
renovate[bot]
9a61453e86 fix(deps): update module github.com/labstack/echo/v4 to v5 (#2131)
Closes https://github.com/go-vikunja/vikunja/pull/2133

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kolaente <k@knt.li>
2026-01-24 20:38:32 +01:00
kolaente
a81a3ee0e5 feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
Dominik Pschenitschni
342bbd6192 fix: correct comments 2025-07-02 17:46:21 +02:00
kolaente
6671ce38a8 chore: rename API test suites (#938) 2025-06-13 08:23:17 +00:00
Dominik Pschenitschni
296577a875 fix: correct license header references (#882)
See originals:
- https://www.gnu.org/licenses/agpl-3.0.txt
- https://www.gnu.org/licenses/gpl-3.0.txt
2025-06-10 12:18:38 +02:00
kolaente
71cad7aa13 chore(auth): refactor creating users in openid and ldap 2025-01-28 09:59:08 +00:00
kolaente
05349ddb5c feat!: config for auth providers now use a map instead of an array
The config values for openid providers now use a map with the provider as key instead of an array. For example before:

auth:
  openid:
    providers:
      - name: foo
        clientid: ...

now becomes:

auth:
  openid:
    providers:
      foo:
        clientid: ...

This allows us to read values for openid providers from files using the same syntax as everywhere and makes the configuration more predictable. It also allows configuring providers through env variables, though it is still required to set at least one value via the config file because Vikunja won't discover the provider otherwise.
2024-11-18 10:34:30 +01:00
kolaente
2063da9eec chore(web): move web handler package to Vikunja 2024-08-29 16:15:28 +02:00
kolaente
e4c71123ef fix: lint 2023-09-01 08:39:25 +02:00
kolaente
fb2a1c59db feat(api tokens): check if a provided token matched a hashed on in the database 2023-09-01 08:36:15 +02:00
kolaente
e518fb1191 chore: remove year from copyright headers
Resolves https://kolaente.dev/vikunja/api/pulls/1483
2023-09-01 08:32:28 +02:00
kolaente
359d0512cc fix: upgrade jwt v5 2023-05-23 16:37:16 +02:00
Dominik Pschenitschni
441722372a feat: add token example 2023-04-03 05:20:01 +00:00
kolaente
349e6a5905 feat: rename lists to projects 2023-03-13 14:28:06 +01:00
konrad
1322cb16d7 feat: add long-lived api tokens (#1085)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/1085
Co-authored-by: konrad <k@knt.li>
Co-committed-by: konrad <k@knt.li>
2022-02-06 13:18:08 +00:00
kolaente
516c812043 feat: expose if a user is a local user through its jwt token 2021-10-31 12:37:31 +01:00
stephen-hill
82a3330412 Added the ability to configure the JWT expiry date using a new server.jwtttl config parameter. (#999)
Co-authored-by: Stephen Hill <stephen@gatekiller.co.uk>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/999
Co-authored-by: stephen-hill <stephen@gatekiller.co.uk>
Co-committed-by: stephen-hill <stephen@gatekiller.co.uk>
2021-10-09 11:02:28 +00:00
renovate
c3da454854 Update module github.com/golang-jwt/jwt to v4 (#930)
Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/930
Co-authored-by: renovate <renovatebot@kolaente.de>
Co-committed-by: renovate <renovatebot@kolaente.de>
2021-08-03 21:43:18 +00:00
kolaente
eae3cbc7bb Replace jwt-go with github.com/golang-jwt/jwt 2021-07-27 10:46:28 +02:00
kolaente
c4a71016b8 Update copyright year 2021-02-02 20:19:13 +01:00
kolaente
9baf6d39bd Change license to AGPLv3 2020-12-23 16:41:52 +01:00
konrad
b2e4fde63a Add email reminders (#743)
Fix tests

Expose email reminder setting through jwt

Set reminders on by default

Fix lint

Make user email configurable

Expose email reminder setting through /info

Don't try to send any reminders if none were found

More spacing for buttons

Fix db time format

Enable reminders by default

Make emails look more like the frontend

Add config to disable it

Add sending emaisl

Add getting all task users and reminding them

Add getting the next reminder in a cron

Move task reminder to separate file

Add cron

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/743
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
2020-12-18 23:21:17 +00:00
kolaente
d1c65935e6 Add name field to users 2020-11-21 21:51:55 +01:00
konrad
2b5c9ae7a8 Authentication with OpenID Connect providers (#713)
Add config docs

Lint

Move provider-related stuff to separate file

Refactor getting auth providers

Fix tests

Fix user tests

Fix openid tests

Add swagger docs

Fix lint

Fix lint issues

Fix checking if the user already exists

Make sure to create a new namespace for new users

Docs

Add tests for openid

Remove unnessecary err check

Consistently return nil users if creating a new user failed

Move sending confirmation email to separate function

Better variable names

Move checks to separate functions

Refactor creating user into seperate file

Fix creating new local users

Test creating new users from different issuers

Generate a random username right away if no preferred username has been given

Add todo

Cache openid providers

Add getting int clientids

Fix migration

Move creating tokens to auth package

Add getting or creating a third party user

Add parsing claims

Add retreiving auth tokens

Add token callback from openid package

Add check for provider key

Add routes

Start adding openid auth handler

Add config for openid auth

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/713
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
2020-11-21 16:38:58 +00:00