Files
authentik/web/src/elements/oauth/UserRefreshTokenList.ts
Ken Sternberg 453f7b8641 web: provide default endpoint api configuration (#10319)
* web: fix esbuild issue with style sheets

Getting ESBuild, Lit, and Storybook to all agree on how to read and parse stylesheets is a serious
pain. This fix better identifies the value types (instances) being passed from various sources in
the repo to the three *different* kinds of style processors we're using (the native one, the
polyfill one, and whatever the heck Storybook does internally).

Falling back to using older CSS instantiating techniques one era at a time seems to do the trick.
It's ugly, but in the face of the aggressive styling we use to avoid Flashes of Unstyled Content
(FLoUC), it's the logic with which we're left.

In standard mode, the following warning appears on the console when running a Flow:

```
Autofocus processing was blocked because a document already has a focused element.
```

In compatibility mode, the following **error** appears on the console when running a Flow:

```
crawler-inject.js:1106 Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
    at initDomMutationObservers (crawler-inject.js:1106:18)
    at crawler-inject.js:1114:24
    at Array.forEach (<anonymous>)
    at initDomMutationObservers (crawler-inject.js:1114:10)
    at crawler-inject.js:1549:1
initDomMutationObservers @ crawler-inject.js:1106
(anonymous) @ crawler-inject.js:1114
initDomMutationObservers @ crawler-inject.js:1114
(anonymous) @ crawler-inject.js:1549
```

Despite this error, nothing seems to be broken and flows work as anticipated.

* Intermediate; prepping for remove that may fail.

* web: provide a default table endpoint configuration

This commit finds 19 places where the exact same configuration is
used to describe a table's API endpoint, and replaces that configuration
with a provided default from a parent class.

While examining the logs for our build, I noted that this particular
sequence is duplicated multiple times throughout our code base,
accounting for a bloat of 169 lines or so of the estimated 5552
lines of bloat.  By providing a default endpoint configuration and
substituting it (mechanically) wherever the default is required,
we reduce our code duplication issue from 9.26% of the codesabe
to 8.99%.

... which is a start.

* Didn't need the duplication.

* remove page argument while we're at it

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

* actually use it everywhere

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

* web: fix inconsistent method signature for LogViewer

Removed the `_page` parameter from LogViewer's apiEndpoint() method.

The `page: number` parameter is no longer a part of this method's signature.

* web: restore reduced page size to Overview:Recent Events card

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2024-07-02 14:55:29 +02:00

107 lines
3.8 KiB
TypeScript

import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { getRelativeTime } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-status-label";
import "@goauthentik/elements/chips/Chip";
import "@goauthentik/elements/chips/ChipGroup";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFFlex from "@patternfly/patternfly/layouts/Flex/flex.css";
import { ExpiringBaseGrantModel, Oauth2Api, TokenModel } from "@goauthentik/api";
@customElement("ak-user-oauth-refresh-token-list")
export class UserOAuthRefreshTokenList extends Table<TokenModel> {
expandable = true;
@property({ type: Number })
userId?: number;
static get styles(): CSSResult[] {
return super.styles.concat(PFFlex);
}
async apiEndpoint(): Promise<PaginatedResponse<TokenModel>> {
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensList({
...(await this.defaultEndpointConfig()),
user: this.userId,
});
}
checkbox = true;
clearOnRefresh = true;
order = "expires";
columns(): TableColumn[] {
return [
new TableColumn(msg("Provider"), "provider"),
new TableColumn(msg("Revoked?"), "revoked"),
new TableColumn(msg("Expires"), "expires"),
new TableColumn(msg("Scopes"), "scope"),
];
}
renderExpanded(item: TokenModel): TemplateResult {
return html` <td role="cell" colspan="4">
<div class="pf-c-table__expandable-row-content">
<div class="pf-l-flex">
<div class="pf-l-flex__item">
<h3>${msg("ID Token")}</h3>
<pre>${item.idToken}</pre>
</div>
</div>
</div>
</td>
<td></td>
<td></td>`;
}
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Refresh Tokens(s)")}
.objects=${this.selectedElements}
.usedBy=${(item: ExpiringBaseGrantModel) => {
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensUsedByList({
id: item.pk,
});
}}
.delete=${(item: ExpiringBaseGrantModel) => {
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensDestroy({
id: item.pk,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
row(item: TokenModel): TemplateResult[] {
return [
html`<a href="#/core/providers/${item.provider?.pk}"> ${item.provider?.name} </a>`,
html`<ak-status-label
type="warning"
?good=${!item.revoked}
good-label=${msg("No")}
bad-label=${msg("Yes")}
></ak-status-label>`,
html`${item.expires
? html`<div>${getRelativeTime(item.expires)}</div>
<small>${item.expires.toLocaleString()}</small>`
: msg("-")}`,
html`<ak-chip-group>
${item.scope.map((scope) => {
return html`<ak-chip .removable=${false}>${scope}</ak-chip>`;
})}
</ak-chip-group>`,
];
}
}