mirror of
https://github.com/goauthentik/authentik
synced 2026-04-26 01:25:02 +02:00
Compare commits
16 Commits
ea4848c7c6
...
hide_apps
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3162788da4 | ||
|
|
49118fc7a5 | ||
|
|
facdc49ac1 | ||
|
|
273db8a462 | ||
|
|
7fa35e98c8 | ||
|
|
8b58bd759c | ||
|
|
7599ed32f9 | ||
|
|
fd154569bc | ||
|
|
ff9ee42762 | ||
|
|
a683948e91 | ||
|
|
f70ec68a0a | ||
|
|
417de0a90d | ||
|
|
43cb397b97 | ||
|
|
39edef01a8 | ||
|
|
e53ed230ce | ||
|
|
7a52921ab3 |
@@ -116,6 +116,7 @@ class ApplicationSerializer(ModelSerializer):
|
||||
"meta_publisher",
|
||||
"policy_engine_mode",
|
||||
"group",
|
||||
"meta_hide",
|
||||
]
|
||||
extra_kwargs = {
|
||||
"backchannel_providers": {"required": False},
|
||||
@@ -279,6 +280,7 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
|
||||
).lower()
|
||||
|
||||
queryset = self._filter_queryset_for_list(self.get_queryset())
|
||||
queryset = queryset.exclude(meta_hide=True)
|
||||
paginator: Pagination = self.paginator
|
||||
paginated_apps = paginator.paginate_queryset(queryset, request)
|
||||
|
||||
|
||||
32
authentik/core/migrations/0058_add_application_meta_hide.py
Normal file
32
authentik/core/migrations/0058_add_application_meta_hide.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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", "0057_remove_user_groups_remove_user_user_permissions_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="application",
|
||||
name="meta_hide",
|
||||
field=models.BooleanField(
|
||||
default=False, help_text="Hide this application from the user dashboard."
|
||||
),
|
||||
),
|
||||
migrations.RunPython(migrate_blank_launch_url, migrations.RunPython.noop),
|
||||
]
|
||||
@@ -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 dashboard.")
|
||||
)
|
||||
|
||||
objects = ApplicationQuerySet.as_manager()
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5215,6 +5215,11 @@
|
||||
"type": "string",
|
||||
"title": "Group"
|
||||
},
|
||||
"meta_hide": {
|
||||
"type": "boolean",
|
||||
"title": "Meta hide",
|
||||
"description": "Hide this application from the user dashboard."
|
||||
},
|
||||
"icon": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
|
||||
8
packages/client-ts/src/models/Application.ts
generated
8
packages/client-ts/src/models/Application.ts
generated
@@ -127,6 +127,12 @@ export interface Application {
|
||||
* @memberof Application
|
||||
*/
|
||||
group?: string;
|
||||
/**
|
||||
* Hide this application from the user dashboard.
|
||||
* @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"],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,6 +87,12 @@ export interface ApplicationRequest {
|
||||
* @memberof ApplicationRequest
|
||||
*/
|
||||
group?: string;
|
||||
/**
|
||||
* Hide this application from the user dashboard.
|
||||
* @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"],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,6 +87,12 @@ export interface PatchedApplicationRequest {
|
||||
* @memberof PatchedApplicationRequest
|
||||
*/
|
||||
group?: string;
|
||||
/**
|
||||
* Hide this application from the user dashboard.
|
||||
* @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"],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34111,6 +34111,9 @@ components:
|
||||
$ref: '#/components/schemas/PolicyEngineMode'
|
||||
group:
|
||||
type: string
|
||||
meta_hide:
|
||||
type: boolean
|
||||
description: Hide this application from the user dashboard.
|
||||
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 dashboard.
|
||||
required:
|
||||
- name
|
||||
- slug
|
||||
@@ -47408,6 +47414,9 @@ components:
|
||||
$ref: '#/components/schemas/PolicyEngineMode'
|
||||
group:
|
||||
type: string
|
||||
meta_hide:
|
||||
type: boolean
|
||||
description: Hide this application from the user dashboard.
|
||||
PatchedAuthenticatorDuoStageRequest:
|
||||
type: object
|
||||
description: AuthenticatorDuoStage Serializer
|
||||
|
||||
@@ -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 user dashboard")}
|
||||
help=${msg(
|
||||
"If checked, this application will not be shown on the user's application library.",
|
||||
)}
|
||||
>
|
||||
</ak-switch-input>
|
||||
<ak-file-search-input
|
||||
name="metaIcon"
|
||||
label=${msg("Icon")}
|
||||
|
||||
@@ -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 user dashboard")}
|
||||
help=${msg(
|
||||
"If checked, this application will not be shown on the user's application library.",
|
||||
)}
|
||||
>
|
||||
</ak-switch-input>
|
||||
<ak-file-search-input
|
||||
name="metaIcon"
|
||||
label=${msg("Icon")}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 the dashboard, use the **Hide from user dashboard** 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.
|
||||
|
||||
|
||||
@@ -104,10 +104,17 @@ 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 user dashboard** 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
|
||||
In earlier versions, hiding an application was done by setting the _Launch URL_ to `blank://blank`. Existing applications using that value are migrated automatically to the _Hide from user dashboard_ toggle on upgrade.
|
||||
:::
|
||||
:::info Hiding application 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 user dashboard** 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.
|
||||
|
||||
Reference in New Issue
Block a user