Compare commits
	
		
			9 Commits
		
	
	
		
			version/20
			...
			web/sdk/em
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a407d903ab | |||
| 7e6f36b0b4 | |||
| 8dd7b0569c | |||
| 616be78e10 | |||
| 7125db1fbd | |||
| 8c7c7c3fee | |||
| bbbd00db22 | |||
| 6d60c5f7c7 | |||
| accf25a626 | 
@ -25,3 +25,31 @@ class BrandMiddleware:
 | 
				
			|||||||
            if locale != "":
 | 
					            if locale != "":
 | 
				
			||||||
                activate(locale)
 | 
					                activate(locale)
 | 
				
			||||||
        return self.get_response(request)
 | 
					        return self.get_response(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BrandCORSAPIMiddleware:
 | 
				
			||||||
 | 
					    """CORS for API requests depending on Brand"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    get_response: Callable[[HttpRequest], HttpResponse]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
 | 
				
			||||||
 | 
					        self.get_response = get_response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_headers(self, request: HttpRequest, response: HttpResponse):
 | 
				
			||||||
 | 
					        response["Access-Control-Allow-Origin"] = "http://localhost:8080"
 | 
				
			||||||
 | 
					        response["Access-Control-Allow-Credentials"] = "true"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __call__(self, request: HttpRequest) -> HttpResponse:
 | 
				
			||||||
 | 
					        if request.method == "OPTIONS":
 | 
				
			||||||
 | 
					            response = HttpResponse(
 | 
				
			||||||
 | 
					                status=200,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            self.set_headers(request, response)
 | 
				
			||||||
 | 
					            response["Access-Control-Allow-Headers"] = (
 | 
				
			||||||
 | 
					                "authorization,sentry-trace,x-authentik-csrf,content-type"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
 | 
				
			||||||
 | 
					            return response
 | 
				
			||||||
 | 
					        response = self.get_response(request)
 | 
				
			||||||
 | 
					        self.set_headers(request, response)
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
        <link rel="shortcut icon" href="{{ brand.branding_favicon }}">
 | 
					        <link rel="shortcut icon" href="{{ brand.branding_favicon }}">
 | 
				
			||||||
        {% block head_before %}
 | 
					        {% block head_before %}
 | 
				
			||||||
        {% endblock %}
 | 
					        {% endblock %}
 | 
				
			||||||
 | 
					        <link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly-base.css' %}">
 | 
				
			||||||
        <link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
 | 
					        <link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
 | 
				
			||||||
        <link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject>
 | 
					        <link rel="stylesheet" type="text/css" href="{% static 'dist/custom.css' %}" data-inject>
 | 
				
			||||||
        {% versioned_script "dist/poly-%v.js" %}
 | 
					        {% versioned_script "dist/poly-%v.js" %}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,12 +16,14 @@ from django.views.decorators.clickjacking import xframe_options_sameorigin
 | 
				
			|||||||
from django.views.generic import View
 | 
					from django.views.generic import View
 | 
				
			||||||
from drf_spectacular.types import OpenApiTypes
 | 
					from drf_spectacular.types import OpenApiTypes
 | 
				
			||||||
from drf_spectacular.utils import OpenApiParameter, PolymorphicProxySerializer, extend_schema
 | 
					from drf_spectacular.utils import OpenApiParameter, PolymorphicProxySerializer, extend_schema
 | 
				
			||||||
 | 
					from rest_framework.exceptions import AuthenticationFailed
 | 
				
			||||||
from rest_framework.permissions import AllowAny
 | 
					from rest_framework.permissions import AllowAny
 | 
				
			||||||
from rest_framework.views import APIView
 | 
					from rest_framework.views import APIView
 | 
				
			||||||
from sentry_sdk import capture_exception, start_span
 | 
					from sentry_sdk import capture_exception, start_span
 | 
				
			||||||
from sentry_sdk.api import set_tag
 | 
					from sentry_sdk.api import set_tag
 | 
				
			||||||
from structlog.stdlib import BoundLogger, get_logger
 | 
					from structlog.stdlib import BoundLogger, get_logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from authentik.api.authentication import bearer_auth, get_authorization_header
 | 
				
			||||||
from authentik.brands.models import Brand
 | 
					from authentik.brands.models import Brand
 | 
				
			||||||
from authentik.core.models import Application
 | 
					from authentik.core.models import Application
 | 
				
			||||||
from authentik.events.models import Event, EventAction, cleanse_dict
 | 
					from authentik.events.models import Event, EventAction, cleanse_dict
 | 
				
			||||||
@ -116,6 +118,14 @@ class FlowExecutorView(APIView):
 | 
				
			|||||||
        super().setup(request, flow_slug=flow_slug)
 | 
					        super().setup(request, flow_slug=flow_slug)
 | 
				
			||||||
        self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug)
 | 
					        self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug)
 | 
				
			||||||
        self._logger = get_logger().bind(flow_slug=flow_slug)
 | 
					        self._logger = get_logger().bind(flow_slug=flow_slug)
 | 
				
			||||||
 | 
					        # Usually flows are authenticated by session, we don't really use rest_framework's
 | 
				
			||||||
 | 
					        # authentication method.
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            user = bearer_auth(get_authorization_header(request))
 | 
				
			||||||
 | 
					            if user:
 | 
				
			||||||
 | 
					                request.user = user
 | 
				
			||||||
 | 
					        except AuthenticationFailed:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
        set_tag("authentik.flow", self.flow.slug)
 | 
					        set_tag("authentik.flow", self.flow.slug)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_invalid_flow(self, exc: FlowNonApplicableException) -> HttpResponse:
 | 
					    def handle_invalid_flow(self, exc: FlowNonApplicableException) -> HttpResponse:
 | 
				
			||||||
 | 
				
			|||||||
@ -248,6 +248,7 @@ MIDDLEWARE = [
 | 
				
			|||||||
    "django.contrib.auth.middleware.AuthenticationMiddleware",
 | 
					    "django.contrib.auth.middleware.AuthenticationMiddleware",
 | 
				
			||||||
    "authentik.core.middleware.RequestIDMiddleware",
 | 
					    "authentik.core.middleware.RequestIDMiddleware",
 | 
				
			||||||
    "authentik.brands.middleware.BrandMiddleware",
 | 
					    "authentik.brands.middleware.BrandMiddleware",
 | 
				
			||||||
 | 
					    "authentik.brands.middleware.BrandCORSAPIMiddleware",
 | 
				
			||||||
    "authentik.events.middleware.AuditMiddleware",
 | 
					    "authentik.events.middleware.AuditMiddleware",
 | 
				
			||||||
    "django.middleware.security.SecurityMiddleware",
 | 
					    "django.middleware.security.SecurityMiddleware",
 | 
				
			||||||
    "django.middleware.common.CommonMiddleware",
 | 
					    "django.middleware.common.CommonMiddleware",
 | 
				
			||||||
 | 
				
			|||||||
@ -41,6 +41,7 @@ const definitions = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const otherFiles = [
 | 
					const otherFiles = [
 | 
				
			||||||
    ["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
 | 
					    ["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
 | 
				
			||||||
 | 
					    ["node_modules/@patternfly/patternfly/patternfly-base.css", "."],
 | 
				
			||||||
    ["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
 | 
					    ["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
 | 
				
			||||||
    ["src/custom.css", "."],
 | 
					    ["src/custom.css", "."],
 | 
				
			||||||
    ["src/common/styles/**", "."],
 | 
					    ["src/common/styles/**", "."],
 | 
				
			||||||
@ -79,6 +80,12 @@ const interfaces = [
 | 
				
			|||||||
    ["polyfill/poly.ts", "."],
 | 
					    ["polyfill/poly.ts", "."],
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const extraTargets = [
 | 
				
			||||||
 | 
					    ["sdk/index.ts", "sdk", { entryNames: "[dir]/[name]" }],
 | 
				
			||||||
 | 
					    ["sdk/user-settings.ts", "sdk/user-settings", { entryNames: "[dir]/[name]" }],
 | 
				
			||||||
 | 
					    ["sdk/flow.ts", "sdk/flow", { entryNames: "[dir]/[name]" }],
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const baseArgs = {
 | 
					const baseArgs = {
 | 
				
			||||||
    bundle: true,
 | 
					    bundle: true,
 | 
				
			||||||
    write: true,
 | 
					    write: true,
 | 
				
			||||||
@ -101,7 +108,11 @@ function getVersion() {
 | 
				
			|||||||
    return version;
 | 
					    return version;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function buildOneSource(source, dest) {
 | 
					function getAllTargets() {
 | 
				
			||||||
 | 
					    return [...interfaces, ...extraTargets];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function buildSingleTarget(source, dest, options) {
 | 
				
			||||||
    const DIST = path.join(__dirname, "./dist", dest);
 | 
					    const DIST = path.join(__dirname, "./dist", dest);
 | 
				
			||||||
    console.log(`[${new Date(Date.now()).toISOString()}] Starting build for target ${source}`);
 | 
					    console.log(`[${new Date(Date.now()).toISOString()}] Starting build for target ${source}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -112,6 +123,7 @@ async function buildOneSource(source, dest) {
 | 
				
			|||||||
            entryPoints: [`./src/${source}`],
 | 
					            entryPoints: [`./src/${source}`],
 | 
				
			||||||
            entryNames: `[dir]/[name]-${getVersion()}`,
 | 
					            entryNames: `[dir]/[name]-${getVersion()}`,
 | 
				
			||||||
            outdir: DIST,
 | 
					            outdir: DIST,
 | 
				
			||||||
 | 
					            ...options,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        const end = Date.now();
 | 
					        const end = Date.now();
 | 
				
			||||||
        console.log(
 | 
					        console.log(
 | 
				
			||||||
@ -124,8 +136,10 @@ async function buildOneSource(source, dest) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function buildAuthentik(interfaces) {
 | 
					async function buildTargets(targets) {
 | 
				
			||||||
    await Promise.allSettled(interfaces.map(([source, dest]) => buildOneSource(source, dest)));
 | 
					    await Promise.allSettled(
 | 
				
			||||||
 | 
					        targets.map(([source, dest, options]) => buildSingleTarget(source, dest, options)),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let timeoutId = null;
 | 
					let timeoutId = null;
 | 
				
			||||||
@ -135,7 +149,7 @@ function debouncedBuild() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    timeoutId = setTimeout(() => {
 | 
					    timeoutId = setTimeout(() => {
 | 
				
			||||||
        console.clear();
 | 
					        console.clear();
 | 
				
			||||||
        buildAuthentik(interfaces);
 | 
					        buildTargets(getAllTargets());
 | 
				
			||||||
    }, 250);
 | 
					    }, 250);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -143,7 +157,7 @@ if (process.argv.length > 2 && (process.argv[2] === "-h" || process.argv[2] ===
 | 
				
			|||||||
    console.log(`Build the authentikUI
 | 
					    console.log(`Build the authentikUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
options:
 | 
					options:
 | 
				
			||||||
  -w, --watch: Build all ${interfaces.length} interfaces
 | 
					  -w, --watch: Build all ${getAllTargets().length} interfaces
 | 
				
			||||||
  -p, --proxy: Build only the polyfills and the loading application
 | 
					  -p, --proxy: Build only the polyfills and the loading application
 | 
				
			||||||
  -h, --help: This help message
 | 
					  -h, --help: This help message
 | 
				
			||||||
`);
 | 
					`);
 | 
				
			||||||
@ -163,11 +177,11 @@ if (process.argv.length > 2 && (process.argv[2] === "-w" || process.argv[2] ===
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
} else if (process.argv.length > 2 && (process.argv[2] === "-p" || process.argv[2] === "--proxy")) {
 | 
					} else if (process.argv.length > 2 && (process.argv[2] === "-p" || process.argv[2] === "--proxy")) {
 | 
				
			||||||
    // There's no watch-for-proxy, sorry.
 | 
					    // There's no watch-for-proxy, sorry.
 | 
				
			||||||
    await buildAuthentik(
 | 
					    await buildTargets(
 | 
				
			||||||
        interfaces.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)),
 | 
					        interfaces.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    process.exit(0);
 | 
					    process.exit(0);
 | 
				
			||||||
} else {
 | 
					} else {
 | 
				
			||||||
    // And the fallback: just build it.
 | 
					    // And the fallback: just build it.
 | 
				
			||||||
    await buildAuthentik(interfaces);
 | 
					    await buildTargets(interfaces);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3057
									
								
								web/sfe/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3057
									
								
								web/sfe/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,28 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    "name": "@goauthentik/web-sfe",
 | 
					 | 
				
			||||||
    "version": "0.0.0",
 | 
					 | 
				
			||||||
    "private": true,
 | 
					 | 
				
			||||||
    "license": "MIT",
 | 
					 | 
				
			||||||
    "dependencies": {
 | 
					 | 
				
			||||||
        "@goauthentik/api": "^2024.6.3-1724414734",
 | 
					 | 
				
			||||||
        "base64-js": "^1.5.1",
 | 
					 | 
				
			||||||
        "bootstrap": "^4.6.1",
 | 
					 | 
				
			||||||
        "formdata-polyfill": "^4.0.10",
 | 
					 | 
				
			||||||
        "jquery": "^3.7.1",
 | 
					 | 
				
			||||||
        "weakmap-polyfill": "^2.0.4"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "scripts": {
 | 
					 | 
				
			||||||
        "build": "rollup -c rollup.config.js --bundleConfigAsCjs",
 | 
					 | 
				
			||||||
        "watch": "rollup -w -c rollup.config.js --bundleConfigAsCjs"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "devDependencies": {
 | 
					 | 
				
			||||||
        "@rollup/plugin-commonjs": "^26.0.1",
 | 
					 | 
				
			||||||
        "@rollup/plugin-node-resolve": "^15.2.3",
 | 
					 | 
				
			||||||
        "@rollup/plugin-swc": "^0.3.1",
 | 
					 | 
				
			||||||
        "@swc/cli": "^0.4.0",
 | 
					 | 
				
			||||||
        "@swc/core": "^1.7.23",
 | 
					 | 
				
			||||||
        "@types/jquery": "^3.5.30",
 | 
					 | 
				
			||||||
        "rollup": "^4.21.2",
 | 
					 | 
				
			||||||
        "rollup-plugin-copy": "^3.5.0"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -7,6 +7,9 @@ export function renderSourceIcon(name: string, iconUrl: string | undefined | nul
 | 
				
			|||||||
            const url = iconUrl.replaceAll("fa://", "");
 | 
					            const url = iconUrl.replaceAll("fa://", "");
 | 
				
			||||||
            return html`<i class="fas ${url}" title="${name}"></i>`;
 | 
					            return html`<i class="fas ${url}" title="${name}"></i>`;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (window.authentik_sdk?.base) {
 | 
				
			||||||
 | 
					            return html`<img src="${window.authentik_sdk?.base}${iconUrl}" alt="${name}" />`;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        return html`<img src="${iconUrl}" alt="${name}" />`;
 | 
					        return html`<img src="${iconUrl}" alt="${name}" />`;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return icon;
 | 
					    return icon;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ import {
 | 
				
			|||||||
    CSRFMiddleware,
 | 
					    CSRFMiddleware,
 | 
				
			||||||
    EventMiddleware,
 | 
					    EventMiddleware,
 | 
				
			||||||
    LoggingMiddleware,
 | 
					    LoggingMiddleware,
 | 
				
			||||||
 | 
					    SDKMiddleware,
 | 
				
			||||||
} from "@goauthentik/common/api/middleware";
 | 
					} from "@goauthentik/common/api/middleware";
 | 
				
			||||||
import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
 | 
					import { EVENT_LOCALE_REQUEST, VERSION } from "@goauthentik/common/constants";
 | 
				
			||||||
import { globalAK } from "@goauthentik/common/global";
 | 
					import { globalAK } from "@goauthentik/common/global";
 | 
				
			||||||
@ -67,8 +68,18 @@ export function getMetaContent(key: string): string {
 | 
				
			|||||||
    return metaEl.content;
 | 
					    return metaEl.content;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function apiBase(): string {
 | 
				
			||||||
 | 
					    if (process.env.AK_API_BASE_PATH) {
 | 
				
			||||||
 | 
					        return process.env.AK_API_BASE_PATH;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (window.authentik_sdk?.base) {
 | 
				
			||||||
 | 
					        return window.authentik_sdk?.base;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return window.location.origin;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const DEFAULT_CONFIG = new Configuration({
 | 
					export const DEFAULT_CONFIG = new Configuration({
 | 
				
			||||||
    basePath: (process.env.AK_API_BASE_PATH || window.location.origin) + "/api/v3",
 | 
					    basePath: `${apiBase()}/api/v3`,
 | 
				
			||||||
    headers: {
 | 
					    headers: {
 | 
				
			||||||
        "sentry-trace": getMetaContent("sentry-trace"),
 | 
					        "sentry-trace": getMetaContent("sentry-trace"),
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -76,6 +87,7 @@ export const DEFAULT_CONFIG = new Configuration({
 | 
				
			|||||||
        new CSRFMiddleware(),
 | 
					        new CSRFMiddleware(),
 | 
				
			||||||
        new EventMiddleware(),
 | 
					        new EventMiddleware(),
 | 
				
			||||||
        new LoggingMiddleware(globalAK().brand),
 | 
					        new LoggingMiddleware(globalAK().brand),
 | 
				
			||||||
 | 
					        new SDKMiddleware(),
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,21 @@ export class CSRFMiddleware implements Middleware {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class SDKMiddleware implements Middleware {
 | 
				
			||||||
 | 
					    token?: string;
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        this.token = window.authentik_sdk?.token;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pre?(context: RequestContext): Promise<FetchParams | void> {
 | 
				
			||||||
 | 
					        if (this.token) {
 | 
				
			||||||
 | 
					            context.init.credentials = "include";
 | 
				
			||||||
 | 
					            // @ts-ignore
 | 
				
			||||||
 | 
					            context.init.headers["Authorization"] = `Bearer ${this.token}`;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return Promise.resolve(context);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class EventMiddleware implements Middleware {
 | 
					export class EventMiddleware implements Middleware {
 | 
				
			||||||
    post?(context: ResponseContext): Promise<Response | void> {
 | 
					    post?(context: ResponseContext): Promise<Response | void> {
 | 
				
			||||||
        const request: RequestInfo = {
 | 
					        const request: RequestInfo = {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,11 @@
 | 
				
			|||||||
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
 | 
					import {
 | 
				
			||||||
 | 
					    Config,
 | 
				
			||||||
 | 
					    ConfigFromJSON,
 | 
				
			||||||
 | 
					    CurrentBrand,
 | 
				
			||||||
 | 
					    CurrentBrandFromJSON,
 | 
				
			||||||
 | 
					    ErrorReportingConfigFromJSON,
 | 
				
			||||||
 | 
					    UiThemeEnum,
 | 
				
			||||||
 | 
					} from "@goauthentik/api";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface GlobalAuthentik {
 | 
					export interface GlobalAuthentik {
 | 
				
			||||||
    _converted?: boolean;
 | 
					    _converted?: boolean;
 | 
				
			||||||
@ -28,9 +35,12 @@ export function globalAK(): GlobalAuthentik {
 | 
				
			|||||||
        return {
 | 
					        return {
 | 
				
			||||||
            config: ConfigFromJSON({
 | 
					            config: ConfigFromJSON({
 | 
				
			||||||
                capabilities: [],
 | 
					                capabilities: [],
 | 
				
			||||||
 | 
					                error_reporting: ErrorReportingConfigFromJSON({}),
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            brand: CurrentBrandFromJSON({
 | 
					            brand: CurrentBrandFromJSON({
 | 
				
			||||||
 | 
					                matched_domain: window.location.host,
 | 
				
			||||||
                ui_footer_links: [],
 | 
					                ui_footer_links: [],
 | 
				
			||||||
 | 
					                ui_theme: window.authentik_sdk?.forceTheme ?? UiThemeEnum.Automatic,
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            versionFamily: "",
 | 
					            versionFamily: "",
 | 
				
			||||||
            versionSubdomain: "",
 | 
					            versionSubdomain: "",
 | 
				
			||||||
@ -40,6 +50,10 @@ export function globalAK(): GlobalAuthentik {
 | 
				
			|||||||
    return ak;
 | 
					    return ak;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isEmbedded() {
 | 
				
			||||||
 | 
					    return !!window.authentik_sdk;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function docLink(path: string): string {
 | 
					export function docLink(path: string): string {
 | 
				
			||||||
    const ak = globalAK();
 | 
					    const ak = globalAK();
 | 
				
			||||||
    // Default case or beta build which should always point to latest
 | 
					    // Default case or beta build which should always point to latest
 | 
				
			||||||
 | 
				
			|||||||
@ -21,9 +21,12 @@ export class WebsocketClient {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    connect(): void {
 | 
					    connect(): void {
 | 
				
			||||||
        if (navigator.webdriver) return;
 | 
					        if (navigator.webdriver) return;
 | 
				
			||||||
        const wsUrl = `${window.location.protocol.replace("http", "ws")}//${
 | 
					        let wsUrl = `${window.location.protocol.replace("http", "ws")}//${
 | 
				
			||||||
            window.location.host
 | 
					            window.location.host
 | 
				
			||||||
        }/ws/client/`;
 | 
					        }/ws/client/`;
 | 
				
			||||||
 | 
					        if (window.authentik_sdk?.base) {
 | 
				
			||||||
 | 
					            wsUrl = `${window.authentik_sdk?.base.replace("http", "ws")}/ws/client/`;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        this.messageSocket = new WebSocket(wsUrl);
 | 
					        this.messageSocket = new WebSocket(wsUrl);
 | 
				
			||||||
        this.messageSocket.addEventListener("open", () => {
 | 
					        this.messageSocket.addEventListener("open", () => {
 | 
				
			||||||
            console.debug(`authentik/ws: connected to ${wsUrl}`);
 | 
					            console.debug(`authentik/ws: connected to ${wsUrl}`);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
 | 
					import { isEmbedded } from "@goauthentik/common/global";
 | 
				
			||||||
import { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
 | 
					import { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
 | 
				
			||||||
import { ModalOrchestrationController } from "@goauthentik/elements/controllers/ModalOrchestrationController.js";
 | 
					import { ModalOrchestrationController } from "@goauthentik/elements/controllers/ModalOrchestrationController.js";
 | 
				
			||||||
import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet";
 | 
					import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { state } from "lit/decorators.js";
 | 
					import { state } from "lit/decorators.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
					import PFVariables from "@patternfly/patternfly/base/patternfly-variables.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { Config, CurrentBrand, LicenseSummary } from "@goauthentik/api";
 | 
					import type { Config, CurrentBrand, LicenseSummary } from "@goauthentik/api";
 | 
				
			||||||
import { UiThemeEnum } from "@goauthentik/api";
 | 
					import { UiThemeEnum } from "@goauthentik/api";
 | 
				
			||||||
@ -43,7 +44,10 @@ export class Interface extends AKElement implements AkInterface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    constructor() {
 | 
					    constructor() {
 | 
				
			||||||
        super();
 | 
					        super();
 | 
				
			||||||
        document.adoptedStyleSheets = [...document.adoptedStyleSheets, ensureCSSStyleSheet(PFBase)];
 | 
					        document.adoptedStyleSheets = [
 | 
				
			||||||
 | 
					            ...document.adoptedStyleSheets,
 | 
				
			||||||
 | 
					            ensureCSSStyleSheet(PFVariables),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
        this[brandContext] = new BrandContextController(this);
 | 
					        this[brandContext] = new BrandContextController(this);
 | 
				
			||||||
        this[configContext] = new ConfigContextController(this);
 | 
					        this[configContext] = new ConfigContextController(this);
 | 
				
			||||||
        this[modalController] = new ModalOrchestrationController(this);
 | 
					        this[modalController] = new ModalOrchestrationController(this);
 | 
				
			||||||
@ -61,7 +65,9 @@ export class Interface extends AKElement implements AkInterface {
 | 
				
			|||||||
        // Instead of calling ._activateTheme() twice, we insert the root document in the call
 | 
					        // Instead of calling ._activateTheme() twice, we insert the root document in the call
 | 
				
			||||||
        // since multiple calls to ._activateTheme() would not do anything after the first call
 | 
					        // since multiple calls to ._activateTheme() would not do anything after the first call
 | 
				
			||||||
        // as the theme is already enabled.
 | 
					        // as the theme is already enabled.
 | 
				
			||||||
        roots.unshift(document as unknown as DocumentOrShadowRoot);
 | 
					        if (!isEmbedded()) {
 | 
				
			||||||
 | 
					            roots.unshift(document as unknown as DocumentOrShadowRoot);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        super._activateTheme(theme, ...roots);
 | 
					        super._activateTheme(theme, ...roots);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import {
 | 
				
			|||||||
    EVENT_FLOW_INSPECTOR_TOGGLE,
 | 
					    EVENT_FLOW_INSPECTOR_TOGGLE,
 | 
				
			||||||
    TITLE_DEFAULT,
 | 
					    TITLE_DEFAULT,
 | 
				
			||||||
} from "@goauthentik/common/constants";
 | 
					} from "@goauthentik/common/constants";
 | 
				
			||||||
import { globalAK } from "@goauthentik/common/global";
 | 
					import { globalAK, isEmbedded } from "@goauthentik/common/global";
 | 
				
			||||||
import { configureSentry } from "@goauthentik/common/sentry";
 | 
					import { configureSentry } from "@goauthentik/common/sentry";
 | 
				
			||||||
import { first } from "@goauthentik/common/utils";
 | 
					import { first } from "@goauthentik/common/utils";
 | 
				
			||||||
import { WebsocketClient } from "@goauthentik/common/ws";
 | 
					import { WebsocketClient } from "@goauthentik/common/ws";
 | 
				
			||||||
@ -84,6 +84,7 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
				
			|||||||
        return [PFBase, PFLogin, PFDrawer, PFButton, PFTitle, PFList, PFBackgroundImage].concat(css`
 | 
					        return [PFBase, PFLogin, PFDrawer, PFButton, PFTitle, PFList, PFBackgroundImage].concat(css`
 | 
				
			||||||
            :host {
 | 
					            :host {
 | 
				
			||||||
                --pf-c-login__main-body--PaddingBottom: var(--pf-global--spacer--2xl);
 | 
					                --pf-c-login__main-body--PaddingBottom: var(--pf-global--spacer--2xl);
 | 
				
			||||||
 | 
					                position: relative;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            .pf-c-background-image::before {
 | 
					            .pf-c-background-image::before {
 | 
				
			||||||
                --pf-c-background-image--BackgroundImage: var(--ak-flow-background);
 | 
					                --pf-c-background-image--BackgroundImage: var(--ak-flow-background);
 | 
				
			||||||
@ -95,9 +96,6 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
				
			|||||||
            .ak-hidden {
 | 
					            .ak-hidden {
 | 
				
			||||||
                display: none;
 | 
					                display: none;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            :host {
 | 
					 | 
				
			||||||
                position: relative;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            .pf-c-drawer__content {
 | 
					            .pf-c-drawer__content {
 | 
				
			||||||
                background-color: transparent;
 | 
					                background-color: transparent;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -262,10 +260,13 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
				
			|||||||
        this.challenge = challenge as ChallengeTypes;
 | 
					        this.challenge = challenge as ChallengeTypes;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setShadowStyles(value: ContextualFlowInfo) {
 | 
					    setBackgroundImage(value: ContextualFlowInfo) {
 | 
				
			||||||
        if (!value) {
 | 
					        if (!value) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (isEmbedded()) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        this.shadowRoot
 | 
					        this.shadowRoot
 | 
				
			||||||
            ?.querySelectorAll<HTMLDivElement>(".pf-c-background-image")
 | 
					            ?.querySelectorAll<HTMLDivElement>(".pf-c-background-image")
 | 
				
			||||||
            .forEach((bg) => {
 | 
					            .forEach((bg) => {
 | 
				
			||||||
@ -276,7 +277,7 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
				
			|||||||
    // DOM post-processing has to happen after the render.
 | 
					    // DOM post-processing has to happen after the render.
 | 
				
			||||||
    updated(changedProperties: PropertyValues<this>) {
 | 
					    updated(changedProperties: PropertyValues<this>) {
 | 
				
			||||||
        if (changedProperties.has("flowInfo") && this.flowInfo !== undefined) {
 | 
					        if (changedProperties.has("flowInfo") && this.flowInfo !== undefined) {
 | 
				
			||||||
            this.setShadowStyles(this.flowInfo);
 | 
					            this.setBackgroundImage(this.flowInfo);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -459,56 +460,63 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    renderCard() {
 | 
				
			||||||
 | 
					        return html`<div class="pf-c-login ${this.getLayout()}">
 | 
				
			||||||
 | 
					            <div class="${this.getLayoutClass()}">
 | 
				
			||||||
 | 
					                <div class="pf-c-login__main">
 | 
				
			||||||
 | 
					                    ${this.loading && this.challenge
 | 
				
			||||||
 | 
					                        ? html`<ak-loading-overlay></ak-loading-overlay>`
 | 
				
			||||||
 | 
					                        : nothing}
 | 
				
			||||||
 | 
					                    ${isEmbedded()
 | 
				
			||||||
 | 
					                        ? nothing
 | 
				
			||||||
 | 
					                        : html` <div class="pf-c-login__main-header pf-c-brand ak-brand">
 | 
				
			||||||
 | 
					                              <img
 | 
				
			||||||
 | 
					                                  src="${themeImage(
 | 
				
			||||||
 | 
					                                      first(
 | 
				
			||||||
 | 
					                                          this.brand?.brandingLogo,
 | 
				
			||||||
 | 
					                                          globalAK()?.brand.brandingLogo,
 | 
				
			||||||
 | 
					                                          DefaultBrand.brandingLogo,
 | 
				
			||||||
 | 
					                                      ),
 | 
				
			||||||
 | 
					                                  )}"
 | 
				
			||||||
 | 
					                                  alt="authentik Logo"
 | 
				
			||||||
 | 
					                              />
 | 
				
			||||||
 | 
					                          </div>`}
 | 
				
			||||||
 | 
					                    ${until(this.renderChallenge())}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                ${isEmbedded()
 | 
				
			||||||
 | 
					                    ? nothing
 | 
				
			||||||
 | 
					                    : html` <footer class="pf-c-login__footer">
 | 
				
			||||||
 | 
					                          <ul class="pf-c-list pf-m-inline">
 | 
				
			||||||
 | 
					                              ${this.brand?.uiFooterLinks?.map((link) => {
 | 
				
			||||||
 | 
					                                  if (link.href) {
 | 
				
			||||||
 | 
					                                      return html`<li>
 | 
				
			||||||
 | 
					                                          <a href="${link.href}">${link.name}</a>
 | 
				
			||||||
 | 
					                                      </li>`;
 | 
				
			||||||
 | 
					                                  }
 | 
				
			||||||
 | 
					                                  return html`<li>
 | 
				
			||||||
 | 
					                                      <span>${link.name}</span>
 | 
				
			||||||
 | 
					                                  </li>`;
 | 
				
			||||||
 | 
					                              })}
 | 
				
			||||||
 | 
					                              <li>
 | 
				
			||||||
 | 
					                                  <span>${msg("Powered by authentik")}</span>
 | 
				
			||||||
 | 
					                              </li>
 | 
				
			||||||
 | 
					                          </ul>
 | 
				
			||||||
 | 
					                      </footer>`}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render(): TemplateResult {
 | 
					    render(): TemplateResult {
 | 
				
			||||||
 | 
					        if (isEmbedded()) {
 | 
				
			||||||
 | 
					            return this.renderCard();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        return html` <ak-locale-context>
 | 
					        return html` <ak-locale-context>
 | 
				
			||||||
            <div class="pf-c-background-image"></div>
 | 
					            <div class="pf-c-background-image"></div>
 | 
				
			||||||
            <div class="pf-c-page__drawer">
 | 
					            <div class="pf-c-page__drawer">
 | 
				
			||||||
                <div class="pf-c-drawer ${this.inspectorOpen ? "pf-m-expanded" : "pf-m-collapsed"}">
 | 
					                <div class="pf-c-drawer ${this.inspectorOpen ? "pf-m-expanded" : "pf-m-collapsed"}">
 | 
				
			||||||
                    <div class="pf-c-drawer__main">
 | 
					                    <div class="pf-c-drawer__main">
 | 
				
			||||||
                        <div class="pf-c-drawer__content">
 | 
					                        <div class="pf-c-drawer__content">
 | 
				
			||||||
                            <div class="pf-c-drawer__body">
 | 
					                            <div class="pf-c-drawer__body">${this.renderCard()}</div>
 | 
				
			||||||
                                <div class="pf-c-login ${this.getLayout()}">
 | 
					 | 
				
			||||||
                                    <div class="${this.getLayoutClass()}">
 | 
					 | 
				
			||||||
                                        <div class="pf-c-login__main">
 | 
					 | 
				
			||||||
                                            ${this.loading && this.challenge
 | 
					 | 
				
			||||||
                                                ? html`<ak-loading-overlay></ak-loading-overlay>`
 | 
					 | 
				
			||||||
                                                : nothing}
 | 
					 | 
				
			||||||
                                            <div
 | 
					 | 
				
			||||||
                                                class="pf-c-login__main-header pf-c-brand ak-brand"
 | 
					 | 
				
			||||||
                                            >
 | 
					 | 
				
			||||||
                                                <img
 | 
					 | 
				
			||||||
                                                    src="${themeImage(
 | 
					 | 
				
			||||||
                                                        first(
 | 
					 | 
				
			||||||
                                                            this.brand?.brandingLogo,
 | 
					 | 
				
			||||||
                                                            globalAK()?.brand.brandingLogo,
 | 
					 | 
				
			||||||
                                                            DefaultBrand.brandingLogo,
 | 
					 | 
				
			||||||
                                                        ),
 | 
					 | 
				
			||||||
                                                    )}"
 | 
					 | 
				
			||||||
                                                    alt="authentik Logo"
 | 
					 | 
				
			||||||
                                                />
 | 
					 | 
				
			||||||
                                            </div>
 | 
					 | 
				
			||||||
                                            ${until(this.renderChallenge())}
 | 
					 | 
				
			||||||
                                        </div>
 | 
					 | 
				
			||||||
                                        <footer class="pf-c-login__footer">
 | 
					 | 
				
			||||||
                                            <ul class="pf-c-list pf-m-inline">
 | 
					 | 
				
			||||||
                                                ${this.brand?.uiFooterLinks?.map((link) => {
 | 
					 | 
				
			||||||
                                                    if (link.href) {
 | 
					 | 
				
			||||||
                                                        return html`<li>
 | 
					 | 
				
			||||||
                                                            <a href="${link.href}">${link.name}</a>
 | 
					 | 
				
			||||||
                                                        </li>`;
 | 
					 | 
				
			||||||
                                                    }
 | 
					 | 
				
			||||||
                                                    return html`<li>
 | 
					 | 
				
			||||||
                                                        <span>${link.name}</span>
 | 
					 | 
				
			||||||
                                                    </li>`;
 | 
					 | 
				
			||||||
                                                })}
 | 
					 | 
				
			||||||
                                                <li>
 | 
					 | 
				
			||||||
                                                    <span>${msg("Powered by authentik")}</span>
 | 
					 | 
				
			||||||
                                                </li>
 | 
					 | 
				
			||||||
                                            </ul>
 | 
					 | 
				
			||||||
                                        </footer>
 | 
					 | 
				
			||||||
                                    </div>
 | 
					 | 
				
			||||||
                                </div>
 | 
					 | 
				
			||||||
                            </div>
 | 
					 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                        ${until(this.renderInspector())}
 | 
					                        ${until(this.renderInspector())}
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -99,6 +99,7 @@ export class IdentificationStage extends BaseStage<
 | 
				
			|||||||
    createHelperForm(): void {
 | 
					    createHelperForm(): void {
 | 
				
			||||||
        const compatMode = "ShadyDOM" in window;
 | 
					        const compatMode = "ShadyDOM" in window;
 | 
				
			||||||
        this.form = document.createElement("form");
 | 
					        this.form = document.createElement("form");
 | 
				
			||||||
 | 
					        this.form.style.display = "none";
 | 
				
			||||||
        document.documentElement.appendChild(this.form);
 | 
					        document.documentElement.appendChild(this.form);
 | 
				
			||||||
        // Only add the additional username input if we're in a shadow dom
 | 
					        // Only add the additional username input if we're in a shadow dom
 | 
				
			||||||
        // otherwise it just confuses browsers
 | 
					        // otherwise it just confuses browsers
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								web/src/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								web/src/global.d.ts
									
									
									
									
										vendored
									
									
								
							@ -12,3 +12,11 @@ declare namespace Intl {
 | 
				
			|||||||
        public format: (items: string[]) => string;
 | 
					        public format: (items: string[]) => string;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare interface Window {
 | 
				
			||||||
 | 
					    authentik_sdk?: {
 | 
				
			||||||
 | 
					        base: string;
 | 
				
			||||||
 | 
					        token?: string;
 | 
				
			||||||
 | 
					        forceTheme?: string;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								web/src/sdk/common.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								web/src/sdk/common.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import { Interface } from "@goauthentik/elements/Interface/Interface";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { html } from "lit";
 | 
				
			||||||
 | 
					import { customElement } from "lit/decorators.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { UiThemeEnum, UiThemeEnumFromJSON } from "@goauthentik/api";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@customElement("ak-sdk-interface")
 | 
				
			||||||
 | 
					export class SDKInterface extends Interface {
 | 
				
			||||||
 | 
					    constructor() {
 | 
				
			||||||
 | 
					        super();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return html`<slot></slot>`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    async getTheme(): Promise<UiThemeEnum> {
 | 
				
			||||||
 | 
					        return UiThemeEnumFromJSON(window.authentik_sdk?.forceTheme) || UiThemeEnum.Automatic;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								web/src/sdk/flow.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								web/src/sdk/flow.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					import "@goauthentik/elements/messages/MessageContainer";
 | 
				
			||||||
 | 
					import { FlowExecutor } from "@goauthentik/flow/FlowExecutor";
 | 
				
			||||||
 | 
					// Statically import some stages to speed up load speed
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/access_denied/AccessDeniedStage";
 | 
				
			||||||
 | 
					// Import webauthn-related stages to prevent issues on safari
 | 
				
			||||||
 | 
					// Which is overly sensitive to allowing things only in the context of a
 | 
				
			||||||
 | 
					// user interaction
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStage";
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/authenticator_webauthn/WebAuthnAuthenticatorRegisterStage";
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/autosubmit/AutosubmitStage";
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/captcha/CaptchaStage";
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/identification/IdentificationStage";
 | 
				
			||||||
 | 
					import "@goauthentik/flow/stages/password/PasswordStage";
 | 
				
			||||||
 | 
					import "@goauthentik/sdk/common";
 | 
				
			||||||
 | 
					// end of stage import
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { html, nothing } from "lit";
 | 
				
			||||||
 | 
					import { customElement } from "lit/decorators.js";
 | 
				
			||||||
 | 
					import { until } from "lit/directives/until.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@customElement("ak-embedded-flow-executor")
 | 
				
			||||||
 | 
					export class EmbeddedFlowExecutor extends FlowExecutor {
 | 
				
			||||||
 | 
					    renderCard() {
 | 
				
			||||||
 | 
					        return html`<div class="pf-c-login">
 | 
				
			||||||
 | 
					            <div class="pf-c-login__main">
 | 
				
			||||||
 | 
					                ${this.loading && this.challenge
 | 
				
			||||||
 | 
					                    ? html`<ak-loading-overlay></ak-loading-overlay>`
 | 
				
			||||||
 | 
					                    : nothing}
 | 
				
			||||||
 | 
					                ${until(this.renderChallenge())}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								web/src/sdk/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								web/src/sdk/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					import "@goauthentik/sdk/flow";
 | 
				
			||||||
 | 
					import "@goauthentik/sdk/user-settings";
 | 
				
			||||||
							
								
								
									
										3
									
								
								web/src/sdk/user-settings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/src/sdk/user-settings.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					import "@goauthentik/elements/messages/MessageContainer";
 | 
				
			||||||
 | 
					import "@goauthentik/sdk/common";
 | 
				
			||||||
 | 
					import "@goauthentik/user/user-settings/UserSettingsPage";
 | 
				
			||||||
@ -21,6 +21,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    ChallengeTypes,
 | 
					    ChallengeTypes,
 | 
				
			||||||
 | 
					    CoreApi,
 | 
				
			||||||
    FlowChallengeResponseRequest,
 | 
					    FlowChallengeResponseRequest,
 | 
				
			||||||
    FlowErrorChallenge,
 | 
					    FlowErrorChallenge,
 | 
				
			||||||
    FlowsApi,
 | 
					    FlowsApi,
 | 
				
			||||||
@ -82,8 +83,11 @@ export class UserSettingsFlowExecutor
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    firstUpdated(): void {
 | 
					    async firstUpdated(): Promise<void> {
 | 
				
			||||||
        this.flowSlug = this.brand?.flowUserSettings;
 | 
					        if (!this.brand) {
 | 
				
			||||||
 | 
					            this.brand = await new CoreApi(DEFAULT_CONFIG).coreBrandsCurrentRetrieve();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.flowSlug = this.brand.flowUserSettings;
 | 
				
			||||||
        if (!this.flowSlug) {
 | 
					        if (!this.flowSlug) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@
 | 
				
			|||||||
            "@goauthentik/flow/*": ["./src/flow/*"],
 | 
					            "@goauthentik/flow/*": ["./src/flow/*"],
 | 
				
			||||||
            "@goauthentik/locales/*": ["./src/locales/*"],
 | 
					            "@goauthentik/locales/*": ["./src/locales/*"],
 | 
				
			||||||
            "@goauthentik/polyfill/*": ["./src/polyfill/*"],
 | 
					            "@goauthentik/polyfill/*": ["./src/polyfill/*"],
 | 
				
			||||||
 | 
					            "@goauthentik/sdk/*": ["./src/sdk/*"],
 | 
				
			||||||
            "@goauthentik/standalone/*": ["./src/standalone/*"],
 | 
					            "@goauthentik/standalone/*": ["./src/standalone/*"],
 | 
				
			||||||
            "@goauthentik/user/*": ["./src/user/*"]
 | 
					            "@goauthentik/user/*": ["./src/user/*"]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user