diff --git a/web/src/elements/user/SessionList.ts b/web/src/elements/user/SessionList.ts new file mode 100644 index 000000000..8ea86c449 --- /dev/null +++ b/web/src/elements/user/SessionList.ts @@ -0,0 +1,60 @@ +import { t } from "@lingui/macro"; +import { customElement, html, property, TemplateResult } from "lit-element"; +import { AKResponse } from "../../api/Client"; +import { Table, TableColumn } from "../table/Table"; + +import "../forms/DeleteForm"; +import { PAGE_SIZE } from "../../constants"; +import { CoreApi, AuthenticatedSession } from "authentik-api"; +import { DEFAULT_CONFIG } from "../../api/Config"; + +@customElement("ak-user-session-list") +export class AuthenticatedSessionList extends Table { + + @property() + targetUser!: string; + + apiEndpoint(page: number): Promise> { + return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsList({ + userUsername: this.targetUser, + ordering: this.order, + page: page, + pageSize: PAGE_SIZE, + }); + } + + order = "-expires"; + + columns(): TableColumn[] { + return [ + new TableColumn(t`Last IP`, "last_ip"), + new TableColumn(t`Browser`, "user_agent"), + new TableColumn(t`Device`, "user_agent"), + new TableColumn(t`Expires`, "expires"), + new TableColumn(""), + ]; + } + + row(item: AuthenticatedSession): TemplateResult[] { + return [ + html`${item.lastIp}`, + html`${item.userAgent.userAgent?.family}`, + html`${item.userAgent.os?.family}`, + html`${item.expires?.toLocaleString()}`, + html` + { + return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsDestroy({ + uuid: item.uuid || "", + }); + }}> + + `, + ]; + } + +} diff --git a/web/src/elements/user/UserConsentList.ts b/web/src/elements/user/UserConsentList.ts index 830bea8e7..468802340 100644 --- a/web/src/elements/user/UserConsentList.ts +++ b/web/src/elements/user/UserConsentList.ts @@ -16,7 +16,7 @@ export class UserConsentList extends Table { apiEndpoint(page: number): Promise> { return new CoreApi(DEFAULT_CONFIG).coreUserConsentList({ user: this.userId, - ordering: "expires", + ordering: this.order, page: page, pageSize: PAGE_SIZE, }); diff --git a/web/src/pages/users/UserViewPage.ts b/web/src/pages/users/UserViewPage.ts index 374713074..097c14ed9 100644 --- a/web/src/pages/users/UserViewPage.ts +++ b/web/src/pages/users/UserViewPage.ts @@ -13,18 +13,19 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css"; import AKGlobal from "../../authentik.css"; -import "../../elements/forms/ModalForm"; import "../../elements/buttons/ActionButton"; import "../../elements/buttons/SpinnerButton"; +import "../../elements/charts/UserChart"; import "../../elements/CodeMirror"; -import "../../elements/Tabs"; import "../../elements/events/ObjectChangelog"; -import "../../elements/user/UserConsentList"; +import "../../elements/events/UserEvents"; +import "../../elements/forms/ModalForm"; import "../../elements/oauth/UserCodeList"; import "../../elements/oauth/UserRefreshList"; -import "../../elements/charts/UserChart"; import "../../elements/PageHeader"; -import "../../elements/events/UserEvents"; +import "../../elements/Tabs"; +import "../../elements/user/SessionList"; +import "../../elements/user/UserConsentList"; import "./UserForm"; import { CoreApi, User } from "authentik-api"; import { DEFAULT_CONFIG } from "../../api/Config"; @@ -176,6 +177,14 @@ export class UserViewPage extends LitElement { +
+
+
+ + +
+
+