Files
authentik/web/src/common/users.ts
T
Simonyi Gergő f7e23295ed core: add digraph group hierarchy (#17050)
* move imports

* core: add digraph group hierarchy

* move to permissions from Group or User to Role

* set group parents on frontend

* do not serialize `GroupParentageNode` directly

* core: enforce unique group name on database level

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use group parents in LDAP provider

* add user-role relationship control to frontend

* move materialized view to be more discoverable

* add guardian to mypy exceptions

* make `Role` a `ManagedModel`

* fixup! make `Role` a `ManagedModel`

* simplify `get_objects_for_user`

* fix flaky unit test

* rename `django-guardian` fork to `ak-guardian`

* add tests around users/groups/roles

* remove unused guardian config variable

* simplify guardian file structure

* clean up frontend

* initial docs

* remove `mode` from `InitialPermissions`

This is no longer needed, since users no longer directly have permissions.

* fixup! Merge branch 'main' into core/add-digraph-group-hierarchy

* clean up docs for managing permissions

* addendums from docs review

* fixup! Merge branch 'main' into core/add-digraph-group-hierarchy

* tweaks

* dewi and tana edits to docs

* tweak

* truly final tweaks, for now

* relabel Role Permissions table

* clarify button label

* fixup! Merge branch 'main' into core/add-digraph-group-hierarchy

* fixup! Merge branch 'main' into core/add-digraph-group-hierarchy

* merge migrations

* fixup! Merge branch 'main' into core/add-digraph-group-hierarchy

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-12-08 12:04:04 +01:00

116 lines
3.1 KiB
TypeScript

import { DEFAULT_CONFIG } from "#common/api/config";
import { isResponseErrorLike } from "#common/errors/network";
import { UIConfig, UserDisplay } from "#common/ui/config";
import { CoreApi, SessionUser, UserSelf } from "@goauthentik/api";
import { match } from "ts-pattern";
export interface ClientSessionPermissions {
editApplications: boolean;
accessAdmin: boolean;
}
/**
* The display name of the current user, according to their UI config settings.
*/
export function formatUserDisplayName(user: UserSelf | null, uiConfig?: UIConfig): string {
if (!user) return "";
const label = match(uiConfig?.navbar.userDisplay)
.with(UserDisplay.username, () => user.username)
.with(UserDisplay.name, () => user.name)
.with(UserDisplay.email, () => user.email)
.with(UserDisplay.none, () => null)
.otherwise(() => user.name || user.username);
return label || "";
}
/**
* Whether the current session is an unauthenticated guest session.
*/
export function isGuest(user: UserSelf | null): boolean {
return user?.pk === -1;
}
/**
* Create a guest session for unauthenticated users.
*
* @see {@linkcode me} for the actual session retrieval.
*/
function createGuestSession(): SessionUser {
const guest: SessionUser = {
user: {
pk: -1,
isSuperuser: false,
isActive: true,
groups: [],
roles: [],
avatar: "",
uid: "",
username: "",
name: "",
settings: {},
systemPermissions: [],
},
};
return guest;
}
let pendingRedirect = false;
/**
* Redirect to the default authentication flow, preserving the current URL as "next" parameter.
*
* @category Session
*/
export function redirectToAuthFlow(nextPathname = "/flows/-/default/authentication/"): void {
if (pendingRedirect) {
console.debug("authentik/users: Redirect already pending, ");
return;
}
const { pathname, search, hash } = window.location;
const authFlowRedirectURL = new URL(nextPathname, window.location.origin);
authFlowRedirectURL.searchParams.set("next", `${pathname}${search}${hash}`);
pendingRedirect = true;
console.debug(
`authentik/users: Redirecting to authentication flow at ${authFlowRedirectURL.href}`,
);
window.location.assign(authFlowRedirectURL);
}
/**
* Retrieve the current user session.
*
* This is a memoized function, so it will only make one request per page load.
*
* @see {@linkcode refreshMe} to force a refresh.
*
* @category Session
*/
export async function me(requestInit?: RequestInit): Promise<SessionUser> {
return new CoreApi(DEFAULT_CONFIG)
.coreUsersMeRetrieve(requestInit)
.catch(async (error: unknown) => {
if (isResponseErrorLike(error)) {
const { response } = error;
if (response.status === 401 || response.status === 403) {
redirectToAuthFlow();
}
}
console.debug("authentik/users: Failed to retrieve user session", error);
return createGuestSession();
});
}