diff --git a/src/Umbraco.Web.UI.Client/apps/auth/e2e/login.spec.ts b/src/Umbraco.Web.UI.Client/apps/auth/e2e/login.spec.ts deleted file mode 100644 index d34e280a56..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/e2e/login.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { expect, test } from '@playwright/test'; - -test('login', async ({ page }) => { - await page.goto('/'); - - // Fill input[name="email"] - await page.locator('input[name="email"]').fill('test@umbraco.com'); - - // Fill input[name="password"] - await page.locator('input[name="password"]').fill('test123456'); - - // Wait for console.log to be called - page.on('console', (message) => { - expect(message.text()).toBe('login'); - }); - - // Click [aria-label="Login"] - await page.locator('[aria-label="Login"]').click(); -}); diff --git a/src/Umbraco.Web.UI.Client/apps/auth/index.html b/src/Umbraco.Web.UI.Client/apps/auth/index.html deleted file mode 100644 index 75922ccae2..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Umbraco Auth - - - - - - - - diff --git a/src/Umbraco.Web.UI.Client/apps/auth/package.json b/src/Umbraco.Web.UI.Client/apps/auth/package.json deleted file mode 100644 index addf6d7ebf..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@umbraco-cms/login", - "version": "0.0.0", - "license": "MIT", - "author": { - "name": "Umbraco HQ", - "email": "backoffice@umbraco.com" - }, - "type": "module", - "module": "dist/main.js", - "files": [ - "dist" - ], - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "build:watch": "vite build --watch", - "preview": "vite preview" - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/playwright.config.ts b/src/Umbraco.Web.UI.Client/apps/auth/playwright.config.ts deleted file mode 100644 index f7bf259530..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/playwright.config.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type { PlaywrightTestConfig } from '@playwright/test'; -import { devices } from '@playwright/test'; - -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// require('dotenv').config(); - -/** - * See https://playwright.dev/docs/test-configuration. - */ -const config: PlaywrightTestConfig = { - testDir: './e2e', - /* Maximum time one test can run for. */ - timeout: 30 * 1000, - expect: { - /** - * Maximum time expect() should wait for the condition to be met. - * For example in `await expect(locator).toHaveText();` - */ - timeout: 5000, - }, - /* Run tests in files in parallel */ - fullyParallel: true, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Base URL to use in actions like `await page.goto('/')`. */ - // baseURL: 'http://localhost:3000', - - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, - - /* Configure projects for major browsers */ - projects: [ - { - name: 'chromium', - use: { - ...devices['Desktop Chrome'], - }, - }, - - { - name: 'firefox', - use: { - ...devices['Desktop Firefox'], - }, - }, - - { - name: 'webkit', - use: { - ...devices['Desktop Safari'], - }, - }, - - /* Test against mobile viewports. */ - // { - // name: 'Mobile Chrome', - // use: { - // ...devices['Pixel 5'], - // }, - // }, - // { - // name: 'Mobile Safari', - // use: { - // ...devices['iPhone 12'], - // }, - // }, - - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { - // channel: 'msedge', - // }, - // }, - // { - // name: 'Google Chrome', - // use: { - // channel: 'chrome', - // }, - // }, - ], - - /* Folder for test artifacts such as screenshots, videos, traces, etc. */ - // outputDir: 'test-results/', - - /* Run your local dev server before starting the tests */ - webServer: { - command: 'npm run dev', - port: 5173, - reuseExistingServer: !process.env.CI, - }, -}; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/apps/auth/public/favicon.svg b/src/Umbraco.Web.UI.Client/apps/auth/public/favicon.svg deleted file mode 100644 index 19acb4bc1e..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/public/favicon.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - diff --git a/src/Umbraco.Web.UI.Client/apps/auth/public/login.jpeg b/src/Umbraco.Web.UI.Client/apps/auth/public/login.jpeg deleted file mode 100644 index 412cd17865..0000000000 Binary files a/src/Umbraco.Web.UI.Client/apps/auth/public/login.jpeg and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/apps/auth/public/umbraco_logo_white.svg b/src/Umbraco.Web.UI.Client/apps/auth/public/umbraco_logo_white.svg deleted file mode 100644 index 3de8e82ed3..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/public/umbraco_logo_white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/apps/auth/public/umbraco_logomark_white.svg b/src/Umbraco.Web.UI.Client/apps/auth/public/umbraco_logomark_white.svg deleted file mode 100644 index 9372e25d3e..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/public/umbraco_logomark_white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts deleted file mode 100644 index 163ece1736..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { css, CSSResultGroup, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; - -@customElement('umb-auth-layout') -export class UmbAuthLayoutElement extends LitElement { - render() { - return html` -
- - - -
- - - -
- `; - } - - static styles: CSSResultGroup = [ - css` - #background { - position: fixed; - overflow: hidden; - background-position: 50%; - background-repeat: no-repeat; - background-size: cover; - background-image: url('login.jpeg'); - width: 100vw; - height: 100vh; - } - - #logo { - position: fixed; - top: var(--uui-size-space-5); - left: var(--uui-size-space-5); - height: 30px; - } - - #logo img { - height: 100%; - } - - #container { - position: relative; - display: flex; - align-items: center; - justify-content: center; - width: 100vw; - height: 100vh; - } - - #box { - width: 500px; - padding: var(--uui-size-space-6) var(--uui-size-space-5) var(--uui-size-space-5) var(--uui-size-space-5); - } - - #email, - #password { - width: 100%; - } - `, - ]; -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-auth-layout': UmbAuthLayoutElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/auth-legacy.context.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/auth-legacy.context.ts deleted file mode 100644 index 42b0679aab..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/auth-legacy.context.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { LoginRequestModel, IUmbAuthContext, LoginResponse } from './types.js'; - -export class UmbAuthLegacyContext implements IUmbAuthContext { - readonly #AUTH_URL = '/umbraco/backoffice/umbracoapi/authentication/postlogin'; - readonly supportsPersistLogin = true; - - login(data: LoginRequestModel): Promise { - throw new Error('Method not implemented.'); - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/auth.context.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/auth.context.ts deleted file mode 100644 index c38afcb618..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/auth.context.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { UmbAuthRepository } from './auth.repository.js'; -import { LoginRequestModel, IUmbAuthContext } from './types.js'; - -export class UmbAuthContext implements IUmbAuthContext { - readonly #AUTH_URL = '/umbraco/management/api/v1/security/back-office'; - readonly supportsPersistLogin = false; - - #authRepository = new UmbAuthRepository(this.#AUTH_URL); - - public async login(data: LoginRequestModel) { - return this.#authRepository.login(data); - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/auth.repository.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/auth.repository.ts deleted file mode 100644 index f615a915c1..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/auth.repository.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { LoginRequestModel } from './types.js'; - -export class UmbAuthRepository { - #authURL = ''; - - constructor(authUrl: string) { - this.#authURL = authUrl; - } - - public async login(data: LoginRequestModel) { - const request = new Request(this.#authURL + '/login', { - method: 'POST', - body: JSON.stringify({ - username: data.username, - password: data.password, - }), - headers: { - 'Content-Type': 'application/json', - }, - }); - const response = await fetch(request); - - //TODO: What kind of data does the old backoffice expect? - //NOTE: this conditionally adds error and data to the response object - return { - status: response.status, - ...(!response.ok && { error: this.#getErrorText(response) }), - ...(response.ok && { data: 'WHAT DATA SHOULD BE RETURNED?' }), - }; - } - - #getErrorText(response: Response) { - switch (response.status) { - case 401: - return 'Oops! It seems like your login credentials are invalid or expired. Please double-check your username and password and try again.'; - - case 500: - return "We're sorry, but the server encountered an unexpected error. Please refresh the page or try again later.."; - - default: - return response.statusText; - } - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/external-login-provider-test.element.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/external-login-provider-test.element.ts deleted file mode 100644 index 7dda2a047e..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/external-login-provider-test.element.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { css, html, LitElement } from 'lit'; -import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { customElement } from 'lit/decorators.js'; - -@customElement('umb-external-login-provider-test') -export class UmbExternalLoginProviderTestElement extends LitElement { - render() { - return html` - Custom External Login Provider -

This is an example of a custom external login provider using the external login provider extension point

- - `; - } - - static styles = [ - UUITextStyles, - css` - :host { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-4); - padding: var(--uui-size-space-5); - border: 1px solid var(--uui-color-border); - background: var(--uui-color-surface-alt); - border-radius: var(--uui-border-radius); - } - p { - margin: 0; - } - `, - ]; -} - -export default UmbExternalLoginProviderTestElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-external-login-provider-test': UmbExternalLoginProviderTestElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/external-login-provider-test2.element.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/external-login-provider-test2.element.ts deleted file mode 100644 index 652293ad27..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/external-login-provider-test2.element.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { css, html, LitElement } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { customElement } from 'lit/decorators.js'; - -@customElement('umb-external-login-provider-test2') -export class UmbExternalLoginProviderTest2Element extends LitElement { - render() { - return html` - Another Custom External Login Provider -

This is an example of another custom external login provider

- - Email - - - - `; - } - - static styles = [ - UUITextStyles, - css` - :host { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-4); - padding: var(--uui-size-space-5); - border: 1px solid var(--uui-color-border); - background: var(--uui-color-surface-alt); - border-radius: var(--uui-border-radius); - } - p { - margin: 0; - } - uui-input { - width: 100%; - } - `, - ]; -} - -export default UmbExternalLoginProviderTest2Element; - -declare global { - interface HTMLElementTagNameMap { - 'umb-external-login-provider-test2': UmbExternalLoginProviderTest2Element; - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts deleted file mode 100644 index 534b6a9cc2..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts +++ /dev/null @@ -1,29 +0,0 @@ -// TODO: could these be renamed as login providers? -import type { ManifestExternalLoginProvider } from '@umbraco-cms/backoffice/extension-registry'; - -export const manifests: Array = [ - { - type: 'externalLoginProvider', - alias: 'Umb.ExternalLoginProvider.Test', - name: 'Test External Login Provider', - elementName: 'umb-external-login-provider-test', - element: () => import('./external-login-provider-test.element.js'), - weight: 2, - meta: { - label: 'Test External Login Provider', - pathname: 'test/test/test', - }, - }, - { - type: 'externalLoginProvider', - alias: 'Umb.ExternalLoginProvider.Test2', - name: 'Test External Login Provider 2', - elementName: 'umb-external-login-provider-test2', - element: () => import('./external-login-provider-test2.element.js'), - weight: 1, - meta: { - label: 'Test External Login Provider 2', - pathname: 'test/test/test', - }, - }, -]; diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts deleted file mode 100644 index 43ef4da338..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import 'element-internals-polyfill'; - -import '@umbraco-ui/uui-css/dist/uui-css.css'; -import '../../../src/css/umb-css.css'; -import '@umbraco-ui/uui'; - -import './login.element.js'; diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts deleted file mode 100644 index d55dd07276..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; - -import type { UUIButtonState } from '@umbraco-ui/uui'; -import type { IUmbAuthContext } from './types.js'; -import { UmbAuthLegacyContext } from './auth-legacy.context.js'; -import { UmbAuthContext } from './auth.context.js'; - -import './auth-layout.element.js'; - -@customElement('umb-login') -export default class UmbLoginElement extends LitElement { - #authContext: IUmbAuthContext; - - @property({ type: String, attribute: 'return-url' }) - returnUrl = ''; - - @property({ type: Boolean }) - isLegacy = false; - - @state() - private _loginState: UUIButtonState = undefined; - - @state() - private _loginError = ''; - - constructor() { - super(); - if (this.isLegacy) { - this.#authContext = new UmbAuthLegacyContext(); - } else { - this.#authContext = new UmbAuthContext(); - } - } - - #handleSubmit = async (e: SubmitEvent) => { - e.preventDefault(); - - const form = e.target as HTMLFormElement; - if (!form) return; - - if (!form.checkValidity()) return; - - const formData = new FormData(form); - - const username = formData.get('email') as string; - const password = formData.get('password') as string; - const persist = formData.has('persist'); - - this._loginState = 'waiting'; - - const response = await this.#authContext.login({ username, password, persist }); - - this._loginError = response.error || ''; - this._loginState = response.error ? 'failed' : 'success'; - - if (response.error) return; - - location.href = this.returnUrl; - }; - - get #greeting() { - return [ - 'Happy super Sunday', - 'Happy marvelous Monday', - 'Happy tubular Tuesday', - 'Happy wonderful Wednesday', - 'Happy thunderous Thursday', - 'Happy funky Friday', - 'Happy Saturday', - ][new Date().getDay()]; - } - - render() { - return html` - -
-

${this.#greeting}

- -
- - Email - - - - - Password - - - - ${this.#authContext.supportsPersistLogin - ? html` - Remember me - ` - : nothing} - - ${this.#renderErrorMessage()} - - -
-
-
-
- `; - } - - #renderErrorMessage() { - if (!this._loginError || this._loginState !== 'failed') return nothing; - - return html`

${this._loginError}

`; - } - - static styles: CSSResultGroup = [ - UUITextStyles, - css` - #email, - #password { - width: 100%; - } - .text-danger { - color: var(--uui-color-danger-standalone); - } - `, - ]; -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-login': UmbLoginElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts deleted file mode 100644 index 3bdfaccdd0..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { type UmbTestRunnerWindow, defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; -import UmbLoginElement from './login.element.js'; - -describe('UmbLogin', () => { - let element: UmbLoginElement; - - beforeEach(async () => { - element = await fixture(html``); - }); - - it('is defined with its own instance', () => { - expect(element).to.be.instanceOf(UmbLoginElement); - }); - - if ((window as UmbTestRunnerWindow).__UMBRACO_TEST_RUN_A11Y_TEST) { - it('passes the a11y audit', async () => { - await expect(element).to.be.accessible(defaultA11yConfig); - }); - } -}); diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/types.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/types.ts deleted file mode 100644 index 114c515c5d..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -export type LoginRequestModel = { - username: string; - password: string; - persist: boolean; -}; - -export interface IUmbAuthContext { - login(data: LoginRequestModel): Promise; - supportsPersistLogin: boolean; -} - -export type LoginResponse = { - data?: string; - error?: string; - status: number; -}; diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/vite-env.d.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/vite-env.d.ts deleted file mode 100644 index b0fda2b4ce..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/vite-env.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// - -/* -interface ImportMetaEnv { -} -*/ diff --git a/src/Umbraco.Web.UI.Client/apps/auth/tsconfig.json b/src/Umbraco.Web.UI.Client/apps/auth/tsconfig.json deleted file mode 100644 index 3f90319d83..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": false - }, - "include": ["src/**/*.ts"], - "references": [ - { - "path": "./tsconfig.node.json" - } - ] -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/tsconfig.node.json b/src/Umbraco.Web.UI.Client/apps/auth/tsconfig.node.json deleted file mode 100644 index b8b8971494..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/tsconfig.node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "esnext", - "moduleResolution": "node", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/src/Umbraco.Web.UI.Client/apps/auth/vite.config.ts b/src/Umbraco.Web.UI.Client/apps/auth/vite.config.ts deleted file mode 100644 index 74cb265ca6..0000000000 --- a/src/Umbraco.Web.UI.Client/apps/auth/vite.config.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { defineConfig } from 'vite'; -import viteTSConfigPaths from 'vite-tsconfig-paths'; - -// https://vitejs.dev/config/ -export default defineConfig({ - build: { - lib: { - entry: 'src/index.ts', - formats: ['es'], - fileName: 'main', - }, - target: 'esnext', - sourcemap: true, - rollupOptions: { - external: [/^@umbraco-cms\/backoffice\//], - output: { - manualChunks: { - uui: ['@umbraco-ui/uui'], - }, - }, - }, - outDir: '../../../Umbraco.Cms.StaticAssets/wwwroot/umbraco/auth', - emptyOutDir: true, - }, - server: { - fs: { - // Allow serving files from the global node_modules folder - allow: ['.', '../../node_modules'], - }, - }, - plugins: [viteTSConfigPaths()], -}); diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index e8c3085c05..33e545c0fa 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -117,7 +117,6 @@ "url": "https://umbraco.com" }, "scripts": { - "auth:test:e2e": "npx playwright test --config apps/auth/", "backoffice:test:e2e": "npx playwright test", "build-storybook": "npm run wc-analyze && storybook build", "build:for:cms": "npm run build && node ./devops/build/copy-to-cms.js", @@ -146,7 +145,7 @@ "preview": "vite preview --open", "storybook:build": "npm run wc-analyze && storybook build", "storybook": "npm run wc-analyze && storybook dev -p 6006", - "test:e2e": "npm run auth:test:e2e && npm run backoffice:test:e2e", + "test:e2e": "npm run backoffice:test:e2e", "test:dev": "web-test-runner --config ./web-test-runner.dev.config.mjs", "test:dev-watch": "web-test-runner --watch --config ./web-test-runner.dev.config.mjs", "test:watch": "web-test-runner --watch",