web/admin: add basic session management UI
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
		
							
								
								
									
										60
									
								
								web/src/elements/user/SessionList.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								web/src/elements/user/SessionList.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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<AuthenticatedSession> { | ||||||
|  |  | ||||||
|  |     @property() | ||||||
|  |     targetUser!: string; | ||||||
|  |  | ||||||
|  |     apiEndpoint(page: number): Promise<AKResponse<AuthenticatedSession>> { | ||||||
|  |         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` | ||||||
|  |             <ak-forms-delete | ||||||
|  |                 .obj=${item} | ||||||
|  |                 objectLabel=${t`Session`} | ||||||
|  |                 .delete=${() => { | ||||||
|  |                     return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsDestroy({ | ||||||
|  |                         uuid: item.uuid || "", | ||||||
|  |                     }); | ||||||
|  |                 }}> | ||||||
|  |                 <button slot="trigger" class="pf-c-button pf-m-danger"> | ||||||
|  |                     ${t`Delete Session`} | ||||||
|  |                 </button> | ||||||
|  |             </ak-forms-delete>`, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -16,7 +16,7 @@ export class UserConsentList extends Table<UserConsent> { | |||||||
|     apiEndpoint(page: number): Promise<AKResponse<UserConsent>> { |     apiEndpoint(page: number): Promise<AKResponse<UserConsent>> { | ||||||
|         return new CoreApi(DEFAULT_CONFIG).coreUserConsentList({ |         return new CoreApi(DEFAULT_CONFIG).coreUserConsentList({ | ||||||
|             user: this.userId, |             user: this.userId, | ||||||
|             ordering: "expires", |             ordering: this.order, | ||||||
|             page: page, |             page: page, | ||||||
|             pageSize: PAGE_SIZE, |             pageSize: PAGE_SIZE, | ||||||
|         }); |         }); | ||||||
|  | |||||||
| @ -13,18 +13,19 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css"; | |||||||
| import PFButton from "@patternfly/patternfly/components/Button/button.css"; | import PFButton from "@patternfly/patternfly/components/Button/button.css"; | ||||||
| import AKGlobal from "../../authentik.css"; | import AKGlobal from "../../authentik.css"; | ||||||
|  |  | ||||||
| import "../../elements/forms/ModalForm"; |  | ||||||
| import "../../elements/buttons/ActionButton"; | import "../../elements/buttons/ActionButton"; | ||||||
| import "../../elements/buttons/SpinnerButton"; | import "../../elements/buttons/SpinnerButton"; | ||||||
|  | import "../../elements/charts/UserChart"; | ||||||
| import "../../elements/CodeMirror"; | import "../../elements/CodeMirror"; | ||||||
| import "../../elements/Tabs"; |  | ||||||
| import "../../elements/events/ObjectChangelog"; | import "../../elements/events/ObjectChangelog"; | ||||||
| import "../../elements/user/UserConsentList"; | import "../../elements/events/UserEvents"; | ||||||
|  | import "../../elements/forms/ModalForm"; | ||||||
| import "../../elements/oauth/UserCodeList"; | import "../../elements/oauth/UserCodeList"; | ||||||
| import "../../elements/oauth/UserRefreshList"; | import "../../elements/oauth/UserRefreshList"; | ||||||
| import "../../elements/charts/UserChart"; |  | ||||||
| import "../../elements/PageHeader"; | import "../../elements/PageHeader"; | ||||||
| import "../../elements/events/UserEvents"; | import "../../elements/Tabs"; | ||||||
|  | import "../../elements/user/SessionList"; | ||||||
|  | import "../../elements/user/UserConsentList"; | ||||||
| import "./UserForm"; | import "./UserForm"; | ||||||
| import { CoreApi, User } from "authentik-api"; | import { CoreApi, User } from "authentik-api"; | ||||||
| import { DEFAULT_CONFIG } from "../../api/Config"; | import { DEFAULT_CONFIG } from "../../api/Config"; | ||||||
| @ -176,6 +177,14 @@ export class UserViewPage extends LitElement { | |||||||
|                         </div> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </section> |                 </section> | ||||||
|  |                 <section slot="page-sessions" data-tab-title="${t`Sessions`}" class="pf-c-page__main-section pf-m-no-padding-mobile"> | ||||||
|  |                     <div class="pf-c-card"> | ||||||
|  |                         <div class="pf-c-card__body"> | ||||||
|  |                             <ak-user-session-list targetUser=${this.user.username}> | ||||||
|  |                             </ak-user-session-list> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </section> | ||||||
|                 <section slot="page-events" data-tab-title="${t`User events`}" class="pf-c-page__main-section pf-m-no-padding-mobile"> |                 <section slot="page-events" data-tab-title="${t`User events`}" class="pf-c-page__main-section pf-m-no-padding-mobile"> | ||||||
|                     <div class="pf-c-card"> |                     <div class="pf-c-card"> | ||||||
|                         <div class="pf-c-card__body"> |                         <div class="pf-c-card__body"> | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer