diff --git a/Pipfile.lock b/Pipfile.lock index 094a814a0..c57c0f093 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -116,18 +116,17 @@ }, "boto3": { "hashes": [ - "sha256:273e96ae2b95a6036a4c3547e76a270b17ab761cc76053823c9e361d268213ef", - "sha256:399ccbd31b7aa09d53c4e449fe575803b033fcc23ed3a1d7ae2fe7a04727a562" + "sha256:64a8900b3a110e2d6ff4d87f4d8cd56f0c8527361d9fc9385fcb50efe7a4975a", + "sha256:8e9ff8006c41889ed8a11831dee62adf922e071f14d54c52946d1f7855ae7a8e" ], "index": "pypi", - "version": "==1.17.25" + "version": "==1.17.26" }, "botocore": { "hashes": [ - "sha256:b80b4efe5fafb29f24a3657d1f77aa170525c876b5fd9384d5e5859d0405206e", - "sha256:f1c04a5e96944b628ae98a2975829125c0e9b99f9be7b118d42fb82cef3c420a" + "sha256:4a785847a351e59f2329627fc9a19cf50f07644ea68996a1595d5a20487a423f" ], - "version": "==1.20.25" + "version": "==1.20.26" }, "cachetools": { "hashes": [ @@ -817,10 +816,10 @@ }, "prompt-toolkit": { "hashes": [ - "sha256:0fa02fa80363844a4ab4b8d6891f62dd0645ba672723130423ca4037b80c1974", - "sha256:62c811e46bd09130fb11ab759012a4ae385ce4fb2073442d1898867a824183bd" + "sha256:4cea7d09e46723885cb8bc54678175453e5071e9449821dce6f017b1d1fbfc1a", + "sha256:9397a7162cf45449147ad6042fa37983a081b8a73363a5253dd4072666333137" ], - "version": "==3.0.16" + "version": "==3.0.17" }, "psycopg2-binary": { "hashes": [ diff --git a/authentik/outposts/channels.py b/authentik/outposts/channels.py index 7ad5b0dfa..d104e1f16 100644 --- a/authentik/outposts/channels.py +++ b/authentik/outposts/channels.py @@ -55,13 +55,21 @@ class OutpostConsumer(AuthJsonConsumer): OutpostState( uid=self.channel_name, last_seen=datetime.now(), _outpost=self.outpost ).save(timeout=OUTPOST_HELLO_INTERVAL * 1.5) - LOGGER.debug("added channel to cache", channel_name=self.channel_name) + LOGGER.debug( + "added outpost instace to cache", + outpost=self.outpost, + channel_name=self.channel_name, + ) # pylint: disable=unused-argument def disconnect(self, close_code): if self.outpost: OutpostState.for_channel(self.outpost, self.channel_name).delete() - LOGGER.debug("removed channel from cache", channel_name=self.channel_name) + LOGGER.debug( + "removed outpost instance from cache", + outpost=self.outpost, + channel_name=self.channel_name, + ) def receive_json(self, content: Data): msg = from_dict(WebsocketMessage, content) diff --git a/outpost/proxy.Dockerfile b/outpost/proxy.Dockerfile index 4551ec110..ad2660723 100644 --- a/outpost/proxy.Dockerfile +++ b/outpost/proxy.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.16.1 AS builder +FROM golang:1.16.2 AS builder WORKDIR /work diff --git a/web/package-lock.json b/web/package-lock.json index 7356f70e7..082c9cdfd 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -143,27 +143,27 @@ } }, "@sentry/browser": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.2.1.tgz", - "integrity": "sha512-OAikFZ9EimD3noxMp8tA6Cf6qJcQ2U8k5QSgTPwdx+09nZOGJzbRFteK7WWmrS93ZJdzN61lpSQbg5v+bmmfbQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.2.2.tgz", + "integrity": "sha512-K5UGyEePtVPZIFMoiRafhd4Ov0M1kdozVsVKIPZrOpJyjQdPNX+fYDNL/h0nVmgOlE2S/uu4fl4mEfe/6aLShw==", "requires": { - "@sentry/core": "6.2.1", - "@sentry/types": "6.2.1", - "@sentry/utils": "6.2.1", + "@sentry/core": "6.2.2", + "@sentry/types": "6.2.2", + "@sentry/utils": "6.2.2", "tslib": "^1.9.3" }, "dependencies": { "@sentry/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.1.tgz", - "integrity": "sha512-h0OV1QT+fv5ojfK5/+iEXClu33HirmvbjcQC2jf05IHj9yXIOWy6EB10S8nBjuLiiFqQiAQYj3FN9Ip4eN8NJA==" + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.2.tgz", + "integrity": "sha512-Y/1sRtw3a5JU4YdNBig8lLSVJ1UdYtuge+QP1CVLcLSAbq07Ok1bvF+Z+BlNcnHqle2Fl8aKuryG5Yu86enOyQ==" }, "@sentry/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-6kQgM/yBPdXu+3qbJnI6HBcWztN9QfiMkH++ZiKk4ERhg9d2LYWlze478uTU5Fyo/JQYcp+McpjtjpR9QIrr0g==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.2.tgz", + "integrity": "sha512-qaee6X6VDNZ8HeO83/veaKw0KuhDE7j1R+Yryme3PywFzsoTzutDrEQjb7gvcHAhBaAYX8IHUBHgxcFI9BxI+w==", "requires": { - "@sentry/types": "6.2.1", + "@sentry/types": "6.2.2", "tslib": "^1.9.3" } }, @@ -175,48 +175,48 @@ } }, "@sentry/core": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.2.1.tgz", - "integrity": "sha512-jPqQEtafxxDtLONhCbTHh/Uq8mZRhsfbwJTSVYfPVEe/ELfFZLQK7tP6rOh7zEWKbTkE0mE6XcaoH3ZRAhgrqg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.2.2.tgz", + "integrity": "sha512-qqWbvvXtymfXh7N5eEvk97MCnMURuyFIgqWdVD4MQM6yIfDCy36CyGfuQ3ViHTLZGdIfEOhLL9/f4kzf1RzqBA==", "requires": { - "@sentry/hub": "6.2.1", - "@sentry/minimal": "6.2.1", - "@sentry/types": "6.2.1", - "@sentry/utils": "6.2.1", + "@sentry/hub": "6.2.2", + "@sentry/minimal": "6.2.2", + "@sentry/types": "6.2.2", + "@sentry/utils": "6.2.2", "tslib": "^1.9.3" }, "dependencies": { "@sentry/hub": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.2.1.tgz", - "integrity": "sha512-pG7wCQeRpzeP6t0bT4T0X029R19dbDS3/qswF8BL6bg0AI3afjfjBAZm/fqn1Uwe/uBoMHVVdbxgJDZeQ5d4rQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.2.2.tgz", + "integrity": "sha512-VR6uQGRYt6RP633FHShlSLj0LUKGVrlTeSlwCoooWM5FR9lmi6akAaweuxpG78/kZvXrAWpjX6/nuYwHKGwzGA==", "requires": { - "@sentry/types": "6.2.1", - "@sentry/utils": "6.2.1", + "@sentry/types": "6.2.2", + "@sentry/utils": "6.2.2", "tslib": "^1.9.3" } }, "@sentry/minimal": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.2.1.tgz", - "integrity": "sha512-wuSXB4Ayxv9rBEQ4pm7fnG4UU2ZPtPnnChoEfd4/mw1UthXSvmPFEn6O4pdo2G8fTkl8eqm6wT/Q7uIXMEmw+A==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.2.2.tgz", + "integrity": "sha512-l0IgoGQgg1lTd4qDU8bQn25sbZBg8PwIHfuTLbGMlRr1flDXHOM1UXajWK/UKbAPelnU7M2JBSVzgl7PwjprzA==", "requires": { - "@sentry/hub": "6.2.1", - "@sentry/types": "6.2.1", + "@sentry/hub": "6.2.2", + "@sentry/types": "6.2.2", "tslib": "^1.9.3" } }, "@sentry/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.1.tgz", - "integrity": "sha512-h0OV1QT+fv5ojfK5/+iEXClu33HirmvbjcQC2jf05IHj9yXIOWy6EB10S8nBjuLiiFqQiAQYj3FN9Ip4eN8NJA==" + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.2.tgz", + "integrity": "sha512-Y/1sRtw3a5JU4YdNBig8lLSVJ1UdYtuge+QP1CVLcLSAbq07Ok1bvF+Z+BlNcnHqle2Fl8aKuryG5Yu86enOyQ==" }, "@sentry/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-6kQgM/yBPdXu+3qbJnI6HBcWztN9QfiMkH++ZiKk4ERhg9d2LYWlze478uTU5Fyo/JQYcp+McpjtjpR9QIrr0g==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.2.tgz", + "integrity": "sha512-qaee6X6VDNZ8HeO83/veaKw0KuhDE7j1R+Yryme3PywFzsoTzutDrEQjb7gvcHAhBaAYX8IHUBHgxcFI9BxI+w==", "requires": { - "@sentry/types": "6.2.1", + "@sentry/types": "6.2.2", "tslib": "^1.9.3" } }, @@ -228,12 +228,12 @@ } }, "@sentry/hub": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.2.1.tgz", - "integrity": "sha512-pG7wCQeRpzeP6t0bT4T0X029R19dbDS3/qswF8BL6bg0AI3afjfjBAZm/fqn1Uwe/uBoMHVVdbxgJDZeQ5d4rQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.2.2.tgz", + "integrity": "sha512-VR6uQGRYt6RP633FHShlSLj0LUKGVrlTeSlwCoooWM5FR9lmi6akAaweuxpG78/kZvXrAWpjX6/nuYwHKGwzGA==", "requires": { - "@sentry/types": "6.2.1", - "@sentry/utils": "6.2.1", + "@sentry/types": "6.2.2", + "@sentry/utils": "6.2.2", "tslib": "^1.9.3" }, "dependencies": { @@ -245,12 +245,12 @@ } }, "@sentry/minimal": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.2.1.tgz", - "integrity": "sha512-wuSXB4Ayxv9rBEQ4pm7fnG4UU2ZPtPnnChoEfd4/mw1UthXSvmPFEn6O4pdo2G8fTkl8eqm6wT/Q7uIXMEmw+A==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.2.2.tgz", + "integrity": "sha512-l0IgoGQgg1lTd4qDU8bQn25sbZBg8PwIHfuTLbGMlRr1flDXHOM1UXajWK/UKbAPelnU7M2JBSVzgl7PwjprzA==", "requires": { - "@sentry/hub": "6.2.1", - "@sentry/types": "6.2.1", + "@sentry/hub": "6.2.2", + "@sentry/types": "6.2.2", "tslib": "^1.9.3" }, "dependencies": { @@ -262,14 +262,14 @@ } }, "@sentry/tracing": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.2.1.tgz", - "integrity": "sha512-bvStY1SnL08wkSeVK3j9K5rivQQJdKFCPR2VYRFOCaUoleZ6ChPUnBvxQ/E2LXc0hk/y/wo1q4r5B0dfCCY+bQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.2.2.tgz", + "integrity": "sha512-mAkPoqtofNfka/u9rOVVDQPaEoTmr0AQh654g9ZqsaqsOJLKjB4FDLVNubWs90fjeKqHiYkI3ZHPak2TzHBPkw==", "requires": { - "@sentry/hub": "6.2.1", - "@sentry/minimal": "6.2.1", - "@sentry/types": "6.2.1", - "@sentry/utils": "6.2.1", + "@sentry/hub": "6.2.2", + "@sentry/minimal": "6.2.2", + "@sentry/types": "6.2.2", + "@sentry/utils": "6.2.2", "tslib": "^1.9.3" }, "dependencies": { @@ -281,16 +281,16 @@ } }, "@sentry/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.1.tgz", - "integrity": "sha512-h0OV1QT+fv5ojfK5/+iEXClu33HirmvbjcQC2jf05IHj9yXIOWy6EB10S8nBjuLiiFqQiAQYj3FN9Ip4eN8NJA==" + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.2.tgz", + "integrity": "sha512-Y/1sRtw3a5JU4YdNBig8lLSVJ1UdYtuge+QP1CVLcLSAbq07Ok1bvF+Z+BlNcnHqle2Fl8aKuryG5Yu86enOyQ==" }, "@sentry/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-6kQgM/yBPdXu+3qbJnI6HBcWztN9QfiMkH++ZiKk4ERhg9d2LYWlze478uTU5Fyo/JQYcp+McpjtjpR9QIrr0g==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.2.tgz", + "integrity": "sha512-qaee6X6VDNZ8HeO83/veaKw0KuhDE7j1R+Yryme3PywFzsoTzutDrEQjb7gvcHAhBaAYX8IHUBHgxcFI9BxI+w==", "requires": { - "@sentry/types": "6.2.1", + "@sentry/types": "6.2.2", "tslib": "^1.9.3" }, "dependencies": { @@ -2653,9 +2653,9 @@ } }, "rollup": { - "version": "2.41.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.41.0.tgz", - "integrity": "sha512-Gk76XHTggulWPH95q8V62bw6uqDH6UGvbD6LOa3QUyhuMF3eOuaeDHR7SLm1T9faitkpNrqzUAVYx47klcMnlA==", + "version": "2.41.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.41.1.tgz", + "integrity": "sha512-nepLFAW5W71/MWpS2Yr7r31eS7HRfYg2RXnxb6ehqN9zY42yACxKtEfb4xq8SmNfUohAzGMcyl6jkwdLOAiUbg==", "requires": { "fsevents": "~2.3.1" } diff --git a/web/package.json b/web/package.json index b18543c2a..e8189514a 100644 --- a/web/package.json +++ b/web/package.json @@ -12,8 +12,8 @@ "dependencies": { "@fortawesome/fontawesome-free": "^5.15.2", "@patternfly/patternfly": "^4.90.5", - "@sentry/browser": "^6.2.1", - "@sentry/tracing": "^6.2.1", + "@sentry/browser": "^6.2.2", + "@sentry/tracing": "^6.2.2", "@types/chart.js": "^2.9.31", "@types/codemirror": "0.0.108", "@types/grecaptcha": "^3.0.1", @@ -24,7 +24,7 @@ "flowchart.js": "^1.15.0", "lit-element": "^2.4.0", "lit-html": "^1.3.0", - "rollup": "^2.41.0", + "rollup": "^2.41.1", "rollup-plugin-copy": "^3.4.0", "rollup-plugin-cssimport": "^1.0.2", "rollup-plugin-external-globals": "^0.6.1", diff --git a/web/src/authentik.css b/web/src/authentik.css index df941a84a..c391694a9 100644 --- a/web/src/authentik.css +++ b/web/src/authentik.css @@ -5,6 +5,12 @@ html { --pf-c-nav__link--PaddingLeft: 0.5rem; } +html > input { + position: absolute; + top: -2000px; + left: -2000px; +} + .pf-c-page__header { z-index: 0; } diff --git a/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts b/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts index 928d4fa36..4e8441629 100644 --- a/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts +++ b/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts @@ -5,6 +5,7 @@ import { BaseStage } from "../base"; import { AuthenticatorValidateStage, AuthenticatorValidateStageChallenge, DeviceChallenge } from "./AuthenticatorValidateStage"; import "../form"; import "../../../elements/utils/LoadingState"; +import { PasswordManagerPrefill } from "../identification/IdentificationStage"; @customElement("ak-stage-authenticator-validate-code") export class AuthenticatorValidateStageWebCode extends BaseStage { @@ -53,6 +54,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage { autofocus="" autocomplete="one-time-code" class="pf-c-form-control" + value="${PasswordManagerPrefill.totp || ""}" required=""> diff --git a/web/src/flows/stages/identification/IdentificationStage.ts b/web/src/flows/stages/identification/IdentificationStage.ts index 3db34d604..f1d632816 100644 --- a/web/src/flows/stages/identification/IdentificationStage.ts +++ b/web/src/flows/stages/identification/IdentificationStage.ts @@ -6,6 +6,14 @@ import "../form"; import "../../../elements/utils/LoadingState"; import { Challenge } from "../../../api/Flows"; +export const PasswordManagerPrefill: { + password: string | undefined; + totp: string | undefined; +} = { + password: undefined, + totp: undefined, +}; + export interface IdentificationChallenge extends Challenge { input_type: string; @@ -41,6 +49,69 @@ export class IdentificationStage extends BaseStage { ); } + firstUpdated(): void { + // This is a workaround for the fact that we're in a shadow dom + // adapted from https://github.com/home-assistant/frontend/issues/3133 + const username = document.createElement("input"); + username.setAttribute("type", "text"); + username.setAttribute("name", "username"); // username as name for high compatibility + username.setAttribute("autocomplete", "username"); + username.onkeyup = (ev: Event) => { + const el = ev.target as HTMLInputElement; + (this.shadowRoot || this).querySelectorAll("input[name=uid_field]").forEach(input => { + input.value = el.value; + // Because we assume only one input field exists that matches this + // call focus so the user can press enter + input.focus(); + }); + }; + document.documentElement.appendChild(username); + const password = document.createElement("input"); + password.setAttribute("type", "password"); + password.setAttribute("name", "password"); + password.setAttribute("autocomplete", "current-password"); + password.onkeyup = (ev: KeyboardEvent) => { + if (ev.key == "Enter") { + this.submitForm(ev); + } + const el = ev.target as HTMLInputElement; + // Because the password field is not actually on this page, + // and we want to 'prefill' the password for the user, + // save it globally + PasswordManagerPrefill.password = el.value; + // Because password managers fill username, then password, + // we need to re-focus the uid_field here too + (this.shadowRoot || this).querySelectorAll("input[name=uid_field]").forEach(input => { + // Because we assume only one input field exists that matches this + // call focus so the user can press enter + input.focus(); + }); + }; + document.documentElement.appendChild(password); + const totp = document.createElement("input"); + totp.setAttribute("type", "text"); + totp.setAttribute("name", "code"); + totp.setAttribute("autocomplete", "one-time-code"); + totp.onkeyup = (ev: KeyboardEvent) => { + if (ev.key == "Enter") { + this.submitForm(ev); + } + const el = ev.target as HTMLInputElement; + // Because the totp field is not actually on this page, + // and we want to 'prefill' the totp for the user, + // save it globally + PasswordManagerPrefill.totp = el.value; + // Because totp managers fill username, then password, then optionally, + // we need to re-focus the uid_field here too + (this.shadowRoot || this).querySelectorAll("input[name=uid_field]").forEach(input => { + // Because we assume only one input field exists that matches this + // call focus so the user can press enter + input.focus(); + }); + }; + document.documentElement.appendChild(totp); + } + renderSource(source: UILoginButton): TemplateResult { let icon = html``; if (source.icon_url) { diff --git a/web/src/flows/stages/password/PasswordStage.ts b/web/src/flows/stages/password/PasswordStage.ts index b7e09ba34..1b2e6dc85 100644 --- a/web/src/flows/stages/password/PasswordStage.ts +++ b/web/src/flows/stages/password/PasswordStage.ts @@ -5,6 +5,7 @@ import { COMMON_STYLES } from "../../../common/styles"; import { BaseStage } from "../base"; import "../form"; import "../../../elements/utils/LoadingState"; +import { PasswordManagerPrefill } from "../identification/IdentificationStage"; export interface PasswordChallenge extends WithUserInfoChallenge { recovery_url?: string; @@ -43,6 +44,7 @@ export class PasswordStage extends BaseStage { + + required="" + value=${PasswordManagerPrefill.password || ""}> ${this.challenge.recovery_url ? diff --git a/website/docs/integrations/services/vmware-vcenter/index.md b/website/docs/integrations/services/vmware-vcenter/index.md index 2597f5ddc..8201db561 100644 --- a/website/docs/integrations/services/vmware-vcenter/index.md +++ b/website/docs/integrations/services/vmware-vcenter/index.md @@ -67,6 +67,10 @@ Create an application which uses this provider. Optionally apply access restrict Set the Launch URL to `https://vcenter.company/ui/login/oauth2`. This will skip vCenter's User Prompt and directly log you in. +:::warning +This Launch URL only works for vCenter < 7.0u2. If you're running 7.0u2 or later, set the launch URL to `https://vcenter.company/ui/login` +::: + ## vCenter Setup Login as local Administrator account (most likely ends with vsphere.local). Using the Menu in the Navigation bar, navigate to _Administration -> Single Sing-on -> Configuration_.