Compare commits

...

23 Commits

Author SHA1 Message Date
Marcelo Elizeche Landó
a3774f3fce generate TS client 2026-04-28 05:24:26 -03:00
Marcelo Elizeche Landó
8ca826cd37 generate schema 2026-04-28 05:09:16 -03:00
Marcelo Elizeche Landó
51bf111640 fix merge conflicts 2026-04-28 03:53:12 -03:00
Marcelo Elizeche Landó
c85a6ad529 rename all mentions of dashboard to My applications 2026-04-28 03:48:26 -03:00
Marcelo Elizeche Landó
5a0d32611b Apply suggestions from code review
Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>
2026-04-28 03:23:48 -03:00
Marcelo Elizeche Landó
578d293b9d fix migrations 2026-04-28 02:56:04 -03:00
Marcelo Elizeche Landó
5058d6af1d fix merge conflict 2026-04-28 02:27:41 -03:00
Marcelo Elizeche Landó
3162788da4 Merge branch 'main' into hide_apps 2026-04-22 09:38:56 -03:00
Marcelo Elizeche Landó
49118fc7a5 Merge branch 'main' into hide_apps 2026-04-22 00:54:28 -03:00
Marcelo Elizeche Landó
facdc49ac1 fix linting 2026-04-21 23:40:00 -03:00
Marcelo Elizeche Landó
273db8a462 Apply suggestions from code review
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>
2026-04-21 23:23:04 -03:00
Jens Langhammer
7fa35e98c8 fix continuous login
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-04-21 14:14:40 +02:00
Marcelo Elizeche Landó
8b58bd759c update docs 2026-04-20 20:41:57 -03:00
Marcelo Elizeche Landó
7599ed32f9 fix tests 2026-04-17 06:54:33 -03:00
Marcelo Elizeche Landó
fd154569bc Convert blank://blank to meta_hide=True in the migration 2026-04-17 06:44:49 -03:00
Marcelo Elizeche Landó
ff9ee42762 Merge branch 'main' into hide_apps 2026-04-17 06:27:33 -03:00
Marcelo Elizeche Landó
a683948e91 fix linting 2026-04-09 16:28:51 -03:00
Marcelo Elizeche Landó
f70ec68a0a Add typescript client changes 2026-04-09 15:28:12 -03:00
Marcelo Elizeche Landó
417de0a90d Add hide setting to application wizard 2026-04-09 15:27:37 -03:00
Marcelo Elizeche Landó
43cb397b97 Add schema 2026-04-09 15:17:37 -03:00
Marcelo Elizeche Landó
39edef01a8 Add the hide option to the UI 2026-04-09 15:11:57 -03:00
Marcelo Elizeche Landó
e53ed230ce exclude hidden applications from user dashboard 2026-04-09 15:11:27 -03:00
Marcelo Elizeche Landó
7a52921ab3 Add meta_hide field to hide apps 2026-04-09 15:10:21 -03:00
15 changed files with 109 additions and 15 deletions

View File

@@ -4,7 +4,7 @@ from collections.abc import Iterator
from copy import copy
from django.core.cache import cache
from django.db.models import Case, Q, QuerySet
from django.db.models import Case, QuerySet
from django.db.models.expressions import When
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext as _
@@ -120,6 +120,7 @@ class ApplicationSerializer(ModelSerializer):
"meta_publisher",
"policy_engine_mode",
"group",
"meta_hide",
]
extra_kwargs = {
"backchannel_providers": {"required": False},
@@ -283,14 +284,12 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
) == "true"
queryset = self._filter_queryset_for_list(self.get_queryset())
queryset = queryset.exclude(meta_hide=True)
if only_with_launch_url:
# Pre-filter at DB level to skip expensive per-app policy evaluation
# for apps that can never appear in the launcher:
# - No meta_launch_url AND no provider: no possible launch URL
# - meta_launch_url="blank://blank": documented convention to hide from launcher
queryset = queryset.exclude(
Q(meta_launch_url="", provider__isnull=True) | Q(meta_launch_url="blank://blank")
)
# for apps that can never appear in the launcher (no meta_launch_url
# and no provider, so no possible launch URL).
queryset = queryset.exclude(meta_launch_url="", provider__isnull=True)
paginator: Pagination = self.paginator
paginated_apps = paginator.paginate_queryset(queryset, request)

View File

@@ -0,0 +1,33 @@
# Generated by Django 5.2.12 on 2026-04-09 18:04
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def migrate_blank_launch_url(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
Application = apps.get_model("authentik_core", "Application")
Application.objects.using(db_alias).filter(meta_launch_url="blank://blank").update(
meta_hide=True, meta_launch_url=""
)
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0058_setup"),
]
operations = [
migrations.AddField(
model_name="application",
name="meta_hide",
field=models.BooleanField(
default=False,
help_text="Hide this application from the user's My applications page.",
),
),
migrations.RunPython(migrate_blank_launch_url, migrations.RunPython.noop),
]

View File

@@ -735,6 +735,9 @@ class Application(SerializerModel, PolicyBindingModel):
meta_icon = FileField(default="", blank=True)
meta_description = models.TextField(default="", blank=True)
meta_publisher = models.TextField(default="", blank=True)
meta_hide = models.BooleanField(
default=False, help_text=_("Hide this application from the user's My applications page.")
)
objects = ApplicationQuerySet.as_manager()

View File

@@ -129,6 +129,7 @@ class TestApplicationsAPI(APITestCase):
"meta_icon_url": None,
"meta_icon_themed_urls": None,
"meta_description": "",
"meta_hide": False,
"meta_publisher": "",
"policy_engine_mode": "any",
},
@@ -187,12 +188,14 @@ class TestApplicationsAPI(APITestCase):
"meta_icon_url": None,
"meta_icon_themed_urls": None,
"meta_description": "",
"meta_hide": False,
"meta_publisher": "",
"policy_engine_mode": "any",
},
{
"launch_url": None,
"meta_description": "",
"meta_hide": False,
"meta_icon": "",
"meta_icon_url": None,
"meta_icon_themed_urls": None,

View File

@@ -353,7 +353,7 @@ class IdentificationStageView(ChallengeStageView):
PLAN_CONTEXT_APPLICATION, Application()
)
challenge.initial_data["application_pre"] = app.name
if launch_url := app.get_launch_url():
if not app.meta_hide and (launch_url := app.get_launch_url()):
challenge.initial_data["application_pre_launch"] = launch_url
if (
PLAN_CONTEXT_DEVICE in self.executor.plan.context

View File

@@ -5215,6 +5215,11 @@
"type": "string",
"title": "Group"
},
"meta_hide": {
"type": "boolean",
"title": "Meta hide",
"description": "Hide this application from the user's My applications page."
},
"icon": {
"type": "string",
"minLength": 1,

View File

@@ -127,6 +127,12 @@ export interface Application {
* @memberof Application
*/
group?: string;
/**
* Hide this application from the user's My applications page.
* @type {boolean}
* @memberof Application
*/
metaHide?: boolean;
}
/**
@@ -177,6 +183,7 @@ export function ApplicationFromJSONTyped(json: any, ignoreDiscriminator: boolean
? undefined
: PolicyEngineModeFromJSON(json["policy_engine_mode"]),
group: json["group"] == null ? undefined : json["group"],
metaHide: json["meta_hide"] == null ? undefined : json["meta_hide"],
};
}
@@ -212,5 +219,6 @@ export function ApplicationToJSONTyped(
meta_publisher: value["metaPublisher"],
policy_engine_mode: PolicyEngineModeToJSON(value["policyEngineMode"]),
group: value["group"],
meta_hide: value["metaHide"],
};
}

View File

@@ -87,6 +87,12 @@ export interface ApplicationRequest {
* @memberof ApplicationRequest
*/
group?: string;
/**
* Hide this application from the user's My applications page.
* @type {boolean}
* @memberof ApplicationRequest
*/
metaHide?: boolean;
}
/**
@@ -125,6 +131,7 @@ export function ApplicationRequestFromJSONTyped(
? undefined
: PolicyEngineModeFromJSON(json["policy_engine_mode"]),
group: json["group"] == null ? undefined : json["group"],
metaHide: json["meta_hide"] == null ? undefined : json["meta_hide"],
};
}
@@ -152,5 +159,6 @@ export function ApplicationRequestToJSONTyped(
meta_publisher: value["metaPublisher"],
policy_engine_mode: PolicyEngineModeToJSON(value["policyEngineMode"]),
group: value["group"],
meta_hide: value["metaHide"],
};
}

View File

@@ -87,6 +87,12 @@ export interface PatchedApplicationRequest {
* @memberof PatchedApplicationRequest
*/
group?: string;
/**
* Hide this application from the user's My applications page.
* @type {boolean}
* @memberof PatchedApplicationRequest
*/
metaHide?: boolean;
}
/**
@@ -125,6 +131,7 @@ export function PatchedApplicationRequestFromJSONTyped(
? undefined
: PolicyEngineModeFromJSON(json["policy_engine_mode"]),
group: json["group"] == null ? undefined : json["group"],
metaHide: json["meta_hide"] == null ? undefined : json["meta_hide"],
};
}
@@ -152,5 +159,6 @@ export function PatchedApplicationRequestToJSONTyped(
meta_publisher: value["metaPublisher"],
policy_engine_mode: PolicyEngineModeToJSON(value["policyEngineMode"]),
group: value["group"],
meta_hide: value["metaHide"],
};
}

View File

@@ -34111,6 +34111,9 @@ components:
$ref: '#/components/schemas/PolicyEngineMode'
group:
type: string
meta_hide:
type: boolean
description: Hide this application from the user's My applications page.
required:
- backchannel_providers_obj
- launch_url
@@ -34192,6 +34195,9 @@ components:
$ref: '#/components/schemas/PolicyEngineMode'
group:
type: string
meta_hide:
type: boolean
description: Hide this application from the user's My applications page.
required:
- name
- slug
@@ -47428,6 +47434,9 @@ components:
$ref: '#/components/schemas/PolicyEngineMode'
group:
type: string
meta_hide:
type: boolean
description: Hide this application from the user's My applications page.
PatchedAuthenticatorDuoStageRequest:
type: object
description: AuthenticatorDuoStage Serializer

View File

@@ -201,6 +201,15 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
)}
>
</ak-switch-input>
<ak-switch-input
name="metaHide"
?checked=${this.instance?.metaHide ?? false}
label=${msg("Hide from My applications")}
help=${msg(
"If checked, this application will not be shown on the user's My applications page.",
)}
>
</ak-switch-input>
<ak-file-search-input
name="metaIcon"
label=${msg("Icon")}

View File

@@ -187,6 +187,15 @@ export class ApplicationWizardApplicationStep extends ApplicationWizardStep {
)}
>
</ak-switch-input>
<ak-switch-input
name="metaHide"
?checked=${app.metaHide ?? false}
label=${msg("Hide from My applications")}
help=${msg(
"If checked, this application will not be shown on the user's My applications page.",
)}
>
</ak-switch-input>
<ak-file-search-input
name="metaIcon"
label=${msg("Icon")}

View File

@@ -40,11 +40,7 @@ export class FlowMultitabController implements ReactiveController {
return;
}
if (
isIdentificationChallenge(challenge) &&
challenge.applicationPreLaunch &&
challenge.applicationPreLaunch !== "blank://blank"
) {
if (isIdentificationChallenge(challenge) && challenge.applicationPreLaunch) {
multiTabOrchestrateLeave();
window.location.assign(challenge.applicationPreLaunch);
return;

View File

@@ -30,7 +30,7 @@ The following options can be configured:
For a reference of all fields available, see [the API schema for the User object](https://api.goauthentik.io/reference/core-users-retrieve/).
Only applications whose launch URL starts with `http://` or `https://` or are relative URLs are shown on the users' **My applications** page. This can also be used to hide applications that shouldn't be visible on the **My applications** page but are still accessible by users, by setting the _Launch URL_ to `blank://blank`.
Only apps with launch URLs that begin with `http://` or `https://`, or that use relative paths, appear on the user's **My applications** page. To keep an app accessible but remove it from that page, use the **Hide from My applications** option (see [Hide applications](./manage_apps.mdx#hide-applications)).
- _Icon (URL)_: Optionally configure an icon for the application. You can select from files uploaded to the [Files](../../customize/files.md) library or enter an absolute URL.

View File

@@ -104,10 +104,14 @@ return {
## Hide applications
To hide an application without modifying its policy settings or removing it, you can simply set the _Launch URL_ to `blank://blank`, which will hide the application from users.
To hide an application without modifying its policy settings or removing it, you can use the **Hide from My applications** option on the application. The application will no longer appear on the **My applications** page.
Keep in mind that users still have access, so they can still authorize access when the login process is started from the application.
:::info Hiding applications before 2026.5
Before authentik 2026.5, an application was hidden by setting its **Launch URL** to `blank://blank`. Existing applications using that value are automatically migrated to using the **Hide from My applications** option upon upgrading.
:::
## Launch URLs
To give users direct links to applications, you can now use a URL like `https://authentik.company/application/launch/<slug>/`. If the user is already logged in, they will be redirected to the application automatically. Otherwise, they'll be sent to the authentication flow and, if successful, forwarded to the application.