wip: rename to authentik (#361)

* root: initial rename

* web: rename custom element prefix

* root: rename external functions with pb_ prefix

* root: fix formatting

* root: replace domain with goauthentik.io

* proxy: update path

* root: rename remaining prefixes

* flows: rename file extension

* root: pbadmin -> akadmin

* docs: fix image filenames

* lifecycle: ignore migration files

* ci: copy default config from current source before loading last tagged

* *: new sentry dsn

* tests: fix missing python3.9-dev package

* root: add additional migrations for service accounts created by outposts

* core: mark system-created service accounts with attribute

* policies/expression: fix pb_ replacement not working

* web: fix last linting errors, add lit-analyse

* policies/expressions: fix lint errors

* web: fix sidebar display on screens where not all items fit

* proxy: attempt to fix proxy pipeline

* proxy: use go env GOPATH to get gopath

* lib: fix user_default naming inconsistency

* docs: add upgrade docs

* docs: update screenshots to use authentik

* admin: fix create button on empty-state of outpost

* web: fix modal submit not refreshing SiteShell and Table

* web: fix height of app-card and height of generic icon

* web: fix rendering of subtext

* admin: fix version check error not being caught

* web: fix worker count not being shown

* docs: update screenshots

* root: new icon

* web: fix lint error

* admin: fix linting error

* root: migrate coverage config to pyproject
This commit is contained in:
Jens L
2020-12-05 22:08:42 +01:00
committed by GitHub
parent 810a7ab50b
commit 1cfe1aff13
989 changed files with 6425 additions and 4412 deletions

View File

@ -6,7 +6,7 @@ interface TickValue {
major: boolean;
}
@customElement("pb-admin-logins-chart")
@customElement("ak-admin-logins-chart")
export class AdminLoginsChart extends LitElement {
@property()
url = "";

View File

@ -7,7 +7,7 @@ import "codemirror/mode/xml/xml.js";
import "codemirror/mode/yaml/yaml.js";
import "codemirror/mode/python/python.js";
@customElement("pb-codemirror")
@customElement("ak-codemirror")
export class CodeMirrorTextarea extends LitElement {
@property({type: Boolean})
readOnly = false;

View File

@ -18,7 +18,7 @@ interface Message {
message: string;
}
@customElement("pb-messages")
@customElement("ak-messages")
export class Messages extends LitElement {
url = DefaultClient.makeUrl(["root", "messages"]);
@ -34,7 +34,7 @@ export class Messages extends LitElement {
try {
this.connect();
} catch (error) {
console.warn(`passbook/messages: failed to connect to ws ${error}`);
console.warn(`authentik/messages: failed to connect to ws ${error}`);
}
}
@ -48,12 +48,12 @@ export class Messages extends LitElement {
}/ws/client/`;
this.messageSocket = new WebSocket(wsUrl);
this.messageSocket.addEventListener("open", () => {
console.debug(`passbook/messages: connected to ${wsUrl}`);
console.debug(`authentik/messages: connected to ${wsUrl}`);
});
this.messageSocket.addEventListener("close", (e) => {
console.debug(`passbook/messages: closed ws connection: ${e}`);
console.debug(`authentik/messages: closed ws connection: ${e}`);
setTimeout(() => {
console.debug(`passbook/messages: reconnecting ws in ${this.retryDelay}ms`);
console.debug(`authentik/messages: reconnecting ws in ${this.retryDelay}ms`);
this.connect();
}, this.retryDelay);
this.retryDelay = this.retryDelay * 2;
@ -63,7 +63,7 @@ export class Messages extends LitElement {
this.renderMessage(data);
});
this.messageSocket.addEventListener("error", (e) => {
console.warn(`passbook/messages: error ${e}`);
console.warn(`authentik/messages: error ${e}`);
this.retryDelay = this.retryDelay * 2;
});
}
@ -72,7 +72,7 @@ export class Messages extends LitElement {
* This mostly gets messages which were created when the user arrives/leaves the site
* and especially the login flow */
fetchMessages(): Promise<void> {
console.debug("passbook/messages: fetching messages over direct api");
console.debug("authentik/messages: fetching messages over direct api");
return fetch(this.url)
.then((r) => r.json())
.then((r: Message[]) => {
@ -85,10 +85,10 @@ export class Messages extends LitElement {
renderMessage(message: Message): void {
const container = <HTMLElement>this.querySelector(".pf-c-alert-group");
if (!container) {
console.warn("passbook/messages: failed to find container");
console.warn("authentik/messages: failed to find container");
return;
}
const id = ID("pb-message");
const id = ID("ak-message");
const el = document.createElement("template");
el.innerHTML = `<li id=${id} class="pf-c-alert-group__item">
<div class="pf-c-alert pf-m-${message.level_tag} ${message.level_tag === "error" ? "pf-m-danger" : ""}">

View File

@ -10,7 +10,7 @@ export enum SpinnerSize {
XLarge = "pf-m-xl",
}
@customElement("pb-spinner")
@customElement("ak-spinner")
export class Spinner extends LitElement {
@property()
size: SpinnerSize = SpinnerSize.Medium;

View File

@ -5,8 +5,9 @@ import TabsStyle from "@patternfly/patternfly/components/Tabs/tabs.css";
// @ts-ignore
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
import { CURRENT_CLASS } from "../constants";
import { gettext } from "django";
@customElement("pb-tabs")
@customElement("ak-tabs")
export class Tabs extends LitElement {
@property()
currentPage?: string;
@ -20,7 +21,7 @@ export class Tabs extends LitElement {
return html` <li class="pf-c-tabs__item ${slot === this.currentPage ? CURRENT_CLASS : ""}">
<button class="pf-c-tabs__link" @click=${() => { this.currentPage = slot; }}>
<span class="pf-c-tabs__item-text">
${page.attributes.getNamedItem("tab-title")?.value}
${page.getAttribute("data-tab-title")}
</span>
</button>
</li>`;
@ -30,7 +31,7 @@ export class Tabs extends LitElement {
const pages = Array.from(this.querySelectorAll("[slot]"));
if (!this.currentPage) {
if (pages.length < 1) {
return html`<h1>no tabs defined</h1>`;
return html`<h1>${gettext("no tabs defined")}</h1>`;
}
this.currentPage = pages[0].attributes.getNamedItem("slot")?.value;
}

View File

@ -3,7 +3,7 @@ import { customElement, property } from "lit-element";
import { ERROR_CLASS, SUCCESS_CLASS } from "../../constants";
import { SpinnerButton } from "./SpinnerButton";
@customElement("pb-action-button")
@customElement("ak-action-button")
export class ActionButton extends SpinnerButton {
@property()
url = "";
@ -13,7 +13,7 @@ export class ActionButton extends SpinnerButton {
return;
}
this.setLoading();
const csrftoken = getCookie("passbook_csrf");
const csrftoken = getCookie("authentik_csrf");
if (!csrftoken) {
console.debug("No csrf token in cookie");
this.setDone(ERROR_CLASS);

View File

@ -1,6 +1,6 @@
import { customElement, html, LitElement, TemplateResult } from "lit-element";
@customElement("pb-dropdown")
@customElement("ak-dropdown")
export class DropdownButton extends LitElement {
constructor() {
super();

View File

@ -14,7 +14,7 @@ import { convertToSlug } from "../../utils";
import { SpinnerButton } from "./SpinnerButton";
import { PRIMARY_CLASS } from "../../constants";
@customElement("pb-modal-button")
@customElement("ak-modal-button")
export class ModalButton extends LitElement {
@property()
href?: string;
@ -92,17 +92,17 @@ export class ModalButton extends LitElement {
if (data.indexOf("csrfmiddlewaretoken") !== -1) {
const modalSlot = this.querySelector("[slot=modal]");
if (!modalSlot) {
console.debug("passbook/modalbutton: modal slot not found?");
console.debug("authentik/modalbutton: modal slot not found?");
return;
}
modalSlot.innerHTML = data;
console.debug("passbook/modalbutton: re-showing form");
console.debug("authentik/modalbutton: re-showing form");
this.updateHandlers();
} else {
this.open = false;
console.debug("passbook/modalbutton: successful submit");
console.debug("authentik/modalbutton: successful submit");
this.dispatchEvent(
new CustomEvent("hashchange", {
new CustomEvent("ak-refresh", {
bubbles: true,
})
);
@ -133,7 +133,7 @@ export class ModalButton extends LitElement {
modalSlot.innerHTML = t;
this.updateHandlers();
this.open = true;
this.querySelectorAll<SpinnerButton>("pb-spinner-button").forEach((sb) => {
this.querySelectorAll<SpinnerButton>("ak-spinner-button").forEach((sb) => {
sb.setDone(PRIMARY_CLASS);
});
})

View File

@ -7,7 +7,7 @@ import ButtonStyle from "@patternfly/patternfly/components/Button/button.css";
import SpinnerStyle from "@patternfly/patternfly/components/Spinner/spinner.css";
import { ColorStyles, PRIMARY_CLASS, PROGRESS_CLASS } from "../../constants";
@customElement("pb-spinner-button")
@customElement("ak-spinner-button")
export class SpinnerButton extends LitElement {
@property({type: Boolean})
isRunning = false;

View File

@ -6,7 +6,7 @@ import ButtonStyle from "@patternfly/patternfly/components/Button/button.css";
import { tokenByIdentifier } from "../../api/token";
import { ColorStyles, ERROR_CLASS, PRIMARY_CLASS, SUCCESS_CLASS } from "../../constants";
@customElement("pb-token-copy-button")
@customElement("ak-token-copy-button")
export class TokenCopyButton extends LitElement {
@property()
identifier?: string;

View File

@ -3,7 +3,7 @@ import { css, CSSResult, customElement, html, LitElement, property, TemplateResu
import { ifDefined } from "lit-html/directives/if-defined";
import { COMMON_STYLES } from "../../common/styles";
@customElement("pb-aggregate-card")
@customElement("ak-aggregate-card")
export class AggregateCard extends LitElement {
@property()
icon?: string;
@ -20,9 +20,6 @@ export class AggregateCard extends LitElement {
font-size: var(--pf-global--icon--FontSize--lg);
text-align: center;
}
.subtext {
font-size: var(--pf-global--FontSize--sm);
}
`]);
}

View File

@ -4,7 +4,7 @@ import { AggregateCard } from "./AggregateCard";
import "../Spinner";
import { SpinnerSize } from "../Spinner";
@customElement("pb-aggregate-card-promise")
@customElement("ak-aggregate-card-promise")
export class AggregatePromiseCard extends AggregateCard {
@property({attribute: false})
promise?: Promise<Record<string, unknown>>;
@ -20,7 +20,7 @@ export class AggregatePromiseCard extends AggregateCard {
renderInner(): TemplateResult {
return html`<p class="center-value">
${until(this.promiseProxy(), html`<pb-spinner size="${SpinnerSize.Large}"></pb-spinner>`)}
${until(this.promiseProxy(), html`<ak-spinner size="${SpinnerSize.Large}"></ak-spinner>`)}
</p>`;
}

View File

@ -18,7 +18,7 @@ export interface SidebarItem {
condition?: () => Promise<boolean>;
}
@customElement("pb-sidebar")
@customElement("ak-sidebar")
export class Sidebar extends LitElement {
@property({attribute: false})
items: SidebarItem[] = [];
@ -36,6 +36,18 @@ export class Sidebar extends LitElement {
max-height: 82px;
margin-bottom: -0.5rem;
}
nav {
display: flex;
flex-direction: column;
max-height: 100vh;
height: 100%;
overflow-y: hidden;
}
.pf-c-nav__list {
flex-grow: 1;
overflow-y: auto;
}
.pf-c-nav__link {
--pf-c-nav__link--PaddingTop: 0.5rem;
--pf-c-nav__link--PaddingRight: 0.5rem;
@ -44,12 +56,6 @@ export class Sidebar extends LitElement {
.pf-c-nav__subnav {
--pf-c-nav__subnav--PaddingBottom: 0px;
}
.pf-c-nav__item-bottom {
position: absolute;
bottom: 0;
width: 100%;
}
`,
];
}
@ -89,18 +95,12 @@ export class Sidebar extends LitElement {
}
render(): TemplateResult {
return html`<div class="pf-c-page__sidebar-body">
<nav class="pf-c-nav" aria-label="Global">
<ul class="pf-c-nav__list">
<li class="pf-c-nav__item sidebar-brand">
<pb-sidebar-brand></pb-sidebar-brand>
</li>
${this.items.map((i) => until(this.renderItem(i), html``))}
<li class="pf-c-nav__item pf-c-nav__item-bottom">
<pb-sidebar-user></pb-sidebar-user>
</li>
</ul>
</nav>
</div>`;
return html`<nav class="pf-c-nav" aria-label="Global">
<ak-sidebar-brand></ak-sidebar-brand>
<ul class="pf-c-nav__list">
${this.items.map((i) => until(this.renderItem(i), html``))}
</ul>
<ak-sidebar-user></ak-sidebar-user>
</nav>`;
}
}

View File

@ -6,15 +6,15 @@ import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
import { Config } from "../../api/config";
export const DefaultConfig: Config = {
branding_logo: " /static/dist/assets/images/logo.svg",
branding_title: "passbook",
branding_logo: " /static/dist/assets/icons/icon_left_brand.svg",
branding_title: "authentik",
error_reporting_enabled: false,
error_reporting_environment: "",
error_reporting_send_pii: false,
};
@customElement("pb-sidebar-brand")
@customElement("ak-sidebar-brand")
export class SidebarBrand extends LitElement {
@property({attribute: false})
config: Config = DefaultConfig;
@ -24,41 +24,28 @@ export class SidebarBrand extends LitElement {
GlobalsStyle,
PageStyle,
css`
.pf-c-brand {
font-family: "DIN 1451 Std";
line-height: 60px;
font-size: 3rem;
color: var(--pf-c-nav__link--m-current--Color);
:host {
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
margin: 0 1rem;
margin-bottom: 1.5rem;
flex-direction: column;
align-items: center;
height: 82px;
}
.pf-c-brand img {
max-height: 60px;
margin-right: 8px;
width: 100%;
padding: 0 .5rem;
}
`,
];
}
constructor() {
super();
firstUpdated(): void {
Config.get().then((c) => (this.config = c));
}
render(): TemplateResult {
if (!this.config) {
return html``;
}
return html` <a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand pb-brand">
<img src="${this.config.branding_logo}" alt="passbook icon" loading="lazy" />
${this.config.branding_title
? html`<span>${this.config.branding_title}</span>`
: ""}
<div class="pf-c-brand ak-brand">
<img src="${this.config.branding_logo}" alt="authentik icon" loading="lazy" />
</div>
</a>`;
}

View File

@ -8,7 +8,7 @@ import AvatarStyle from "@patternfly/patternfly/components/Avatar/avatar.css";
import { User } from "../../api/user";
import { until } from "lit-html/directives/until";
@customElement("pb-sidebar-user")
@customElement("ak-sidebar-user")
export class SidebarUser extends LitElement {
static get styles(): CSSResult[] {
return [

View File

@ -21,6 +21,13 @@ export abstract class Table<T> extends LitElement {
return COMMON_STYLES;
}
constructor() {
super();
this.addEventListener("ak-refresh", () => {
this.fetch();
});
}
public fetch(): void {
this.apiEndpoint(this.page).then((r) => {
this.data = r;
@ -74,15 +81,15 @@ export abstract class Table<T> extends LitElement {
<slot name="create-button"></slot>
<button
@click=${() => {this.fetch();}}
class="pf-c-button pf-m-primary"
>
class="pf-c-button pf-m-primary">
${gettext("Refresh")}
</button>
</div>
<pb-table-pagination
<ak-table-pagination
class="pf-c-toolbar__item pf-m-pagination"
.table=${this}
></pb-table-pagination>
.pages=${this.data?.pagination}
.pageChangeHandler=${(page: number) => {this.page = page; }}>
</ak-table-pagination>
</div>
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-md">
@ -96,10 +103,11 @@ export abstract class Table<T> extends LitElement {
</tbody>
</table>
<div class="pf-c-pagination pf-m-bottom">
<pb-table-pagination
<ak-table-pagination
class="pf-c-toolbar__item pf-m-pagination"
.table=${this}
></pb-table-pagination>
.pages=${this.data?.pagination}
.pageChangeHandler=${(page: number) => { this.page = page; }}>
</ak-table-pagination>
</div>`;
}

View File

@ -1,41 +1,29 @@
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { Table } from "./Table";
import { COMMON_STYLES } from "../../common/styles";
import { PBPagination } from "../../api/client";
@customElement("pb-table-pagination")
@customElement("ak-table-pagination")
export class TablePagination extends LitElement {
@property({attribute: false})
table?: Table<unknown>;
pages?: PBPagination;
@property({attribute: false})
// eslint-disable-next-line
pageChangeHandler: (page: number) => void = (page: number) => {}
static get styles(): CSSResult[] {
return COMMON_STYLES;
}
previousHandler(): void {
if (!this.table?.data?.pagination.previous) {
console.debug("passbook/tables: no previous");
return;
}
this.table.page = this.table?.data?.pagination.previous;
}
nextHandler(): void {
if (!this.table?.data?.pagination.next) {
console.debug("passbook/tables: no next");
return;
}
this.table.page = this.table?.data?.pagination.next;
}
render(): TemplateResult {
return html` <div class="pf-c-pagination pf-m-compact pf-m-hidden pf-m-visible-on-md">
<div class="pf-c-pagination pf-m-compact pf-m-compact pf-m-hidden pf-m-visible-on-md">
<div class="pf-c-options-menu">
<div class="pf-c-options-menu__toggle pf-m-text pf-m-plain">
<span class="pf-c-options-menu__toggle-text">
${this.table?.data?.pagination.start_index} -
${this.table?.data?.pagination.end_index} of
${this.table?.data?.pagination.count}
${this.pages?.start_index} -
${this.pages?.end_index} of
${this.pages?.count}
</span>
</div>
</div>
@ -43,8 +31,8 @@ export class TablePagination extends LitElement {
<div class="pf-c-pagination__nav-control pf-m-prev">
<button
class="pf-c-button pf-m-plain"
@click=${() => {this.previousHandler();}}
?disabled="${(this.table?.data?.pagination.previous || 0) > 0}"
@click=${() => { this.pageChangeHandler(this.pages?.previous || 0); }}
?disabled="${(this.pages?.previous || 0) > 0}"
aria-label="{% trans 'Go to previous page' %}"
>
<i class="fas fa-angle-left" aria-hidden="true"></i>
@ -53,8 +41,8 @@ export class TablePagination extends LitElement {
<div class="pf-c-pagination__nav-control pf-m-next">
<button
class="pf-c-button pf-m-plain"
@click=${() => {this.nextHandler();}}
?disabled="${(this.table?.data?.pagination.next || 0) > 0}"
@click=${() => { this.pageChangeHandler(this.pages?.next || 0); }}
?disabled="${(this.pages?.next || 0) > 0}"
aria-label="{% trans 'Go to next page' %}"
>
<i class="fas fa-angle-right" aria-hidden="true"></i>