vikunja/pkg/models
kolaente 970f3c3733 fix(auth): build OIDC end-session URL with id_token_hint and post_logout_redirect_uri
On OIDC logout Vikunja redirected to the configured `logouturl` with no query
parameters, so it never sent `id_token_hint` or `post_logout_redirect_uri`.
RP-Initiated-Logout-compliant providers (e.g. PocketID) then ignored the
post-logout redirect and left the user on the IdP's own login page.

This builds the end-session URL server-side from the OpenID Connect
RP-Initiated Logout 1.0 spec:

- id_token_hint (§2, RECOMMENDED): the ID token previously issued to the
  session. It lets the OP skip the logout-confirmation prompt and is what makes
  the OP honor post_logout_redirect_uri (the OP MAY require it, §3).
- post_logout_redirect_uri (§2, OPTIONAL): where the OP redirects after logout.
  MUST be pre-registered with the OP. Defaults to service.publicurl so the user
  lands back on Vikunja.
- client_id (§2, OPTIONAL): the RP client id; the OP verifies it matches the
  id_token_hint.

The end_session_endpoint is discovered from the provider's discovery document
(§2.1, REQUIRED metadata) and falls back to the static `logouturl` config when
the provider does not publish one.

To replay id_token_hint, the raw ID token (and the provider key) are persisted
on the session at the OIDC callback (new migration adds oidc_id_token /
oidc_provider_key columns to the sessions table). At logout the server reads
them, builds the URL, deletes the session, and returns the URL in the logout
response so the frontend redirects to it.

Security note: the raw ID token is stored at rest in the sessions table
(json:"-", never exposed over the API) and removed when the session is deleted
on logout.

Spec: OpenID Connect RP-Initiated Logout 1.0
https://openid.net/specs/openid-connect-rpinitiated-1_0.html

Fixes #2820
2026-06-19 16:06:26 +02:00
..
admin_bypass.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
admin_bypass_test.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
admin_overview.go refactor(admin): extract shared admin overview, user-create and user-view helpers 2026-06-11 19:32:42 +00:00
admin_project_list.go feat(admin): add users/projects list endpoints and is_admin patch 2026-04-20 18:55:06 +00:00
admin_user_actions.go refactor(admin): share user-mutation logic between v1 and v2 2026-06-11 19:32:42 +00:00
admin_user_create.go refactor(admin): extract shared admin overview, user-create and user-view helpers 2026-06-11 19:32:42 +00:00
api_routes.go fix(api/v2): expose v2-only token route groups via the routes endpoint 2026-06-08 13:54:09 +00:00
api_routes_test.go fix(api/v2): expose v2-only token route groups via the routes endpoint 2026-06-08 13:54:09 +00:00
api_tokens.go feat(events): add auth boundary events 2026-06-12 08:56:08 +00:00
api_tokens_expiry_cron.go test: add tests for API token expiry notifications and cron 2026-03-30 12:28:15 +00:00
api_tokens_expiry_cron_test.go test: add tests for API token expiry notifications and cron 2026-03-30 12:28:15 +00:00
api_tokens_expiry_notification.go feat: add Atom feed for user notifications with API token auth (#2758) 2026-05-15 17:25:09 +02:00
api_tokens_expiry_notification_test.go test: add tests for API token expiry notifications and cron 2026-03-30 12:28:15 +00:00
api_tokens_permissions.go feat(api): bot token support via /tokens CRUD and bot_users_enabled flag 2026-05-01 14:44:10 +00:00
api_tokens_test.go feat: add Atom feed for user notifications with API token auth (#2758) 2026-05-15 17:25:09 +02:00
bot_users.go feat(api/v2): add bot user CRUD on /api/v2 2026-06-05 08:51:39 +00:00
bot_users_permissions.go feat(models): add BotUser CRUD wrapper 2026-05-01 14:44:10 +00:00
bot_users_test.go feat(models): add BotUser CRUD wrapper 2026-05-01 14:44:10 +00:00
bulk_task.go docs(api/v2): tag bulk task fields for the v2 schema 2026-06-09 20:13:02 +00:00
bulk_task_test.go chore(deps): update golangci-lint to 2.6.0 (#1737) 2025-10-31 17:28:52 +00:00
comment_quotes.go feat(comments): treat quoted comment authors as implicit mentions 2026-05-20 21:02:14 +00:00
comment_quotes_test.go feat(comments): treat quoted comment authors as implicit mentions 2026-05-20 21:02:14 +00:00
error.go feat(api/v2): add user data export endpoints 2026-06-17 18:39:38 +00:00
events.go refactor(events): use a concrete doer on project and team events 2026-06-12 08:56:08 +00:00
export.go fix(export): treat a missing export meta row as no export in the status 2026-06-17 18:39:38 +00:00
export_test.go fix(export): treat a missing export meta row as no export in the status 2026-06-17 18:39:38 +00:00
favorites.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
kanban.go refactor(tasks): drop in-memory task dedup, rely on unique index 2026-06-17 21:16:41 +00:00
kanban_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
kanban_task_bucket.go fix(kanban): upsert race condition in kanban task bucket sync (#2938) 2026-06-19 10:09:00 +02:00
kanban_task_bucket_test.go fix(kanban): upsert race condition in kanban task bucket sync (#2938) 2026-06-19 10:09:00 +02:00
kanban_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
label.go docs(api/v2): mark server-controlled label and user fields read-only 2026-05-31 15:27:44 +02:00
label_permissions.go feat(labels): let bot owners manage labels created by their bots 2026-06-09 11:40:04 +00:00
label_task.go docs(api/v2): tag bulk label fields for the v2 schema 2026-06-10 11:56:05 +02:00
label_task_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
label_task_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
label_test.go feat(labels): let bot owners manage labels created by their bots 2026-06-09 11:40:04 +00:00
link_sharing.go docs(api/v2): tag LinkSharing fields for the v2 schema 2026-06-05 09:17:25 +00:00
link_sharing_permissions.go fix(link-sharing): resolve share read permission via project id so by-id reads work 2026-06-05 09:17:25 +00:00
link_sharing_test.go fix(security): validate link share JWTs against DB on every request 2026-04-09 15:38:07 +00:00
listeners.go refactor(events): use a concrete doer on project and team events 2026-06-12 08:56:08 +00:00
main_test.go refactor: remove environment variable requirements for go test 2026-02-17 18:01:05 +01:00
mentions.go feat: format user mentions with display names in email notifications (#1930) 2025-12-10 12:39:05 +01:00
mentions_test.go test: add tests for conversational email system 2026-03-08 16:03:47 +01:00
message.go feat(api/v2): upload user avatar via multipart 2026-06-02 11:55:25 +00:00
metrics_count_test.go test(metrics): verify counts are read from the right table 2026-05-30 13:48:01 +00:00
models.go test(time-tracking): cover the time_entries model 2026-06-08 13:54:09 +00:00
notifications.go feat: add Atom feed for user notifications with API token auth (#2758) 2026-05-15 17:25:09 +02:00
notifications_database.go fix(notifications): refresh embedded users when reading notifications 2026-06-17 21:18:04 +00:00
notifications_refresh.go fix(notifications): log unexpected user refresh failures 2026-06-17 21:18:04 +00:00
notifications_refresh_test.go fix(notifications): refresh embedded users when reading notifications 2026-06-17 21:18:04 +00:00
notifications_test.go feat: add Atom feed for user notifications with API token auth (#2758) 2026-05-15 17:25:09 +02:00
oauth_codes.go feat: add OAuth 2.0 authorization code model and migration 2026-03-27 23:05:04 +00:00
permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
project.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
project_duplicate.go feat(projects): make duplicating shares opt-in (#2932) 2026-06-19 10:15:58 +02:00
project_duplicate_test.go feat(projects): make duplicating shares opt-in (#2932) 2026-06-19 10:15:58 +02:00
project_permissions.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
project_permissions_multiple_teams_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
project_repair.go feat: add repair-projects CLI command 2026-02-25 11:56:25 +01:00
project_repair_test.go feat: add repair-projects CLI command 2026-02-25 11:56:25 +01:00
project_team.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
project_team_permissions.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
project_team_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
project_test.go test(project): pin archived propagation aggregation in ReadAll CTE 2026-04-11 17:20:53 +00:00
project_users.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
project_users_permissions.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
project_users_permissions_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
project_users_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
project_view.go fix(api/v2): scope project view delete to its parent project 2026-06-01 13:04:34 +00:00
project_view_permissions.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
reaction.go docs(api/v2): tag reaction fields for the v2 schema 2026-06-09 21:34:22 +00:00
reaction_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
reaction_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
saved_filter_positions_test.go fix(tasks): prevent duplicate task_positions rows and stale identifiers 2026-06-17 21:16:41 +00:00
saved_filters.go docs(api/v2): tag SavedFilter fields for the v2 schema 2026-06-07 10:40:20 +00:00
saved_filters_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
saved_filters_test.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
sessions.go fix(auth): build OIDC end-session URL with id_token_hint and post_logout_redirect_uri 2026-06-19 16:06:26 +02:00
sessions_permissions.go feat: add Session model with CRUD, permissions, and cleanup cron 2026-02-25 10:30:25 +01:00
setup_tests.go test(time-tracking): cover the time_entries model 2026-06-08 13:54:09 +00:00
subscription.go feat(api/v2): add subscribe/unsubscribe on /api/v2 2026-06-07 09:57:51 +00:00
subscription_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
subscription_test.go fix: prevent session leaks and visibility issues in model tests 2026-02-25 11:03:02 +01:00
task_assignees.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
task_assignees_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
task_assignees_test.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
task_attachment.go docs(api/v2): tag task attachment fields for the v2 schema 2026-06-10 10:22:39 +00:00
task_attachment_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
task_attachment_test.go fix(files): derive file size from reader at creation boundary 2026-04-09 16:22:56 +00:00
task_collection.go feat(models): let TaskCollection force a flat task list 2026-06-11 18:31:03 +00:00
task_collection_filter.go refactor: extract preprocessFilterString from task filter parsing 2026-06-08 13:54:09 +00:00
task_collection_filter_test.go fix(filter): recover from datemath panic on malformed date filter values 2026-02-26 16:09:13 +01:00
task_collection_sort.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
task_collection_sort_test.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
task_collection_test.go refactor(tasks): drop in-memory task dedup, rely on unique index 2026-06-17 21:16:41 +00:00
task_comment_permissions.go fix(sharing): make editing link share comments work 2025-10-09 10:53:18 +02:00
task_comments.go docs(task-comments): trim comments to the non-obvious why 2026-06-03 19:57:26 +00:00
task_comments_test.go refactor(events): pass context to DispatchPending directly 2026-06-12 08:56:08 +00:00
task_duplicate.go feat(api/v2): add task duplicate action (#2815) 2026-06-01 14:13:39 +02:00
task_duplicate_test.go feat: add task duplicate backend model and tests 2026-03-04 17:20:26 +01:00
task_overdue_reminder.go feat: extend WebhookListener for user-level webhooks 2026-03-08 19:45:53 +01:00
task_overdue_reminder_test.go feat: extend WebhookListener for user-level webhooks 2026-03-08 19:45:53 +01:00
task_position.go perf(tasks): batch task position existence check into one query 2026-06-17 21:16:41 +00:00
task_position_test.go fix: catch ErrNeedsFullRecalculation in task creation position conflict resolution 2026-04-09 07:25:57 +00:00
task_relation.go docs(api/v2): tag task relation fields for the v2 schema 2026-06-09 20:42:00 +00:00
task_relation_authz_test.go fix: use recursive CTE in accessibleProjectIDsSubquery for inherited project permissions 2026-04-05 12:20:35 +00:00
task_relation_permissions.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
task_relation_test.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
task_reminder.go feat: extend WebhookListener for user-level webhooks 2026-03-08 19:45:53 +01:00
task_reminder_test.go feat: extend WebhookListener for user-level webhooks 2026-03-08 19:45:53 +01:00
task_search.go fix(tasks): include tasks with deleted parents in subtask-expanded queries 2026-04-02 16:30:23 +00:00
task_search_bench_test.go refactor(tasks): drop in-memory task dedup, rely on unique index 2026-06-17 21:16:41 +00:00
task_search_test.go fix(kanban): make bucket query fixed per-view (#1007) 2025-06-25 11:38:24 +00:00
task_unread_statuses.go feat: task unread tracking (#1857) 2025-11-27 15:14:42 +01:00
tasks.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
tasks_permissions.go refactor(models): remove *Arr helper fields now handled by normalizer 2026-05-31 12:56:57 +00:00
tasks_test.go refactor(events): pass context to DispatchPending directly 2026-06-12 08:56:08 +00:00
team_members.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
team_members_permissions.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
team_members_test.go fix: cleanup team memberships, assignments and subscriptions when users lose access to a project 2025-10-09 13:33:27 +02:00
team_sync.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
teams.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
teams_permissions.go feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00
teams_permissions_test.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
teams_test.go feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
time_tracking.go fix(time-tracking): reject inverted time-entry intervals 2026-06-08 13:54:09 +00:00
time_tracking_filter.go feat(time-tracking): filter time entries with the task DSL 2026-06-08 13:54:09 +00:00
time_tracking_test.go refactor(events): pass context to DispatchPending directly 2026-06-12 08:56:08 +00:00
unsplash.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
user_delete.go feat(models): add BotUser CRUD wrapper 2026-05-01 14:44:10 +00:00
user_delete_test.go fix(models): allow user-delete cascade to complete for disabled creators 2026-05-06 16:08:16 +02:00
user_list_test.go feat(user): always include own bots in user search 2026-05-01 14:44:10 +00:00
user_project.go refactor(user): share user-search logic between v1 and v2 2026-06-11 20:07:43 +00:00
user_project_test.go feat: show user export status in settings (#1200) 2025-07-30 15:50:26 +00:00
user_settings.go feat(audit): attribute failed logins to the originating request 2026-06-12 08:56:08 +00:00
users.go fix(notifications): use full user so notifications show display name 2026-06-18 20:57:05 +00:00
webhooks.go feat(api/v2): add user webhooks on /api/v2 2026-06-10 19:12:41 +00:00
webhooks_permissions.go feat: add user_id to webhooks and user-directed event infrastructure 2026-03-08 19:45:53 +01:00