remove temp login screen
This commit is contained in:
@@ -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();
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Umbraco Auth</title>
|
||||
<script type="module" src="/src/index.ts"></script>
|
||||
<base href="/" />
|
||||
</head>
|
||||
|
||||
<body class="uui-font uui-text" style="margin: 0; padding: 0; overflow: hidden">
|
||||
<umb-login></umb-login>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#3544B1;}
|
||||
.st1{fill:#3544B1;}
|
||||
</style>
|
||||
<path class="st1" d="M0,20C0,8.9,9,0,20,0s20,9,20,20s-9,20-20,20C8.9,40,0,31,0,20L0,20z M19.6,26.8c-1.6,0-3.1-0.1-4.6-0.4
|
||||
c-1.1-0.2-2.1-1-2.5-2c-0.5-1-0.7-2.6-0.7-4.8c0-1.1,0.1-2.3,0.2-3.4c0.1-1.1,0.3-2,0.4-2.7l0.1-0.7c0,0,0,0,0-0.1
|
||||
c0-0.2-0.1-0.4-0.3-0.4l-2.6-0.4H9.6c-0.2,0-0.4,0.1-0.4,0.3c0,0.2-0.1,0.3-0.1,0.7c-0.1,0.8-0.3,1.5-0.4,2.6
|
||||
c-0.2,1.2-0.3,2.4-0.3,3.5c-0.1,0.8-0.1,1.6,0,2.5c0.1,2.2,0.4,3.9,1.1,5.2c0.7,1.3,1.9,2.2,3.5,2.8c1.6,0.6,3.9,0.9,6.9,0.8h0.4
|
||||
c2.9,0,5.2-0.3,6.9-0.8c1.6-0.6,2.8-1.5,3.5-2.8c0.7-1.3,1.1-3.1,1.1-5.2c0.1-0.8,0.1-1.6,0-2.5c0-1.2-0.1-2.4-0.3-3.5
|
||||
c-0.1-1.1-0.3-1.8-0.4-2.6c-0.1-0.4-0.1-0.5-0.1-0.7c0-0.2-0.2-0.3-0.4-0.3h-0.1l-2.6,0.4c-0.2,0-0.3,0.2-0.3,0.4c0,0,0,0,0,0.1
|
||||
l0.1,0.7c0.1,0.7,0.3,1.6,0.4,2.7c0.1,1.1,0.2,2.3,0.2,3.4c0,2.2-0.2,3.8-0.7,4.8c-0.5,1-1.4,1.8-2.5,2c-1.5,0.3-3.1,0.5-4.6,0.4
|
||||
L19.6,26.8z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 316"><path d="M.2 157.8C.3 70.6 71.1-.1 158.3.1S316.2 71 316.1 158.2s-70.8 157.7-157.9 157.7C70.8 315.9.1 245.1.2 157.8zm154.7 54.1c-12.3.4-24.5-.7-36.5-3.3-8.8-1.8-16.3-7.8-19.9-16-3.6-8.2-5.3-20.9-5.2-38.1.1-9 .6-17.9 1.7-26.8 1-8.7 2.1-15.8 3.1-21.5l1.1-5.6v-.5c0-1.6-1.1-2.9-2.6-3.2l-20.4-3.2h-.4c-1.5 0-2.8 1-3.1 2.5-.3 1.3-.6 2.3-1.2 5.4-1.2 6-2.2 11.8-3.4 20.4-1.3 9.3-2 18.6-2.3 27.9-.4 6.5-.4 13 0 19.6.5 17.3 3.4 31.1 8.9 41.4 5.5 10.3 14.7 17.8 27.7 22.3s31.2 6.8 54.4 6.7h2.9c23.3.1 41.4-2.1 54.4-6.7 13-4.5 22.2-12 27.7-22.3s8.4-24.1 8.9-41.4c.4-6.5.4-13 0-19.6-.3-9.3-1-18.7-2.3-27.9-1.2-8.4-2.3-14.3-3.4-20.4-.6-3.1-.8-4.1-1.2-5.4-.3-1.4-1.6-2.5-3.1-2.5h-.5l-20.4 3.2c-1.6.3-2.7 1.6-2.7 3.2v.5l1.1 5.6c1 5.6 2.1 12.8 3.1 21.5 1 8.9 1.6 17.9 1.7 26.8.2 17.1-1.6 29.8-5.2 38.1-3.6 8.2-11 14.2-19.8 16.1-12 2.5-24.2 3.6-36.5 3.3l-6.6-.1zm932.3-43.9c0-30.4 8.6-51.7 43.8-51.7s43.8 21.3 43.8 51.7-8.6 51.7-43.8 51.7-43.8-21.3-43.8-51.7zm65.3 0c0-21.1-2.7-33.1-21.5-33.1s-21.5 12-21.5 33.1 2.8 33.1 21.5 33.1c18.8 0 21.5-12 21.5-33.1zm-672.1 47.8c.5.9 1.5 1.5 2.5 1.4h8.2c1.6 0 2.9-1.3 2.9-2.9v-92.7c0-1.6-1.3-2.9-2.9-2.9h-16.3c-1.6 0-2.9 1.3-2.9 2.9v73.6c-7 3.9-14.9 5.9-22.8 5.8-10.4 0-15.6-4.5-15.6-14.6v-64.8c0-1.6-1.3-2.9-2.9-2.9h-16.4c-1.6 0-2.9 1.3-2.9 2.9v66.7c0 18.9 8.9 31.3 33.9 31.3 11.4-.1 22.6-3.7 32-10.2l2.9 6.5.3-.1zm184.1-68.1c0-18.7-9.3-31.4-32.6-31.4-11.3 0-22.3 3.4-31.6 9.8-4.1-6.1-12-9.8-25.3-9.8-10.7.2-21.1 3.8-29.7 10.2l-2.9-6.5c-.5-.9-1.5-1.5-2.5-1.4h-8.3c-1.6 0-2.9 1.3-2.9 2.9v92.8c0 1.6 1.3 2.9 2.9 2.9h16.3c1.6 0 2.9-1.3 2.9-2.9v-73.5c6.2-3.8 13.4-5.8 20.7-5.8 8.9 0 14 3.3 14 12.6v66.7c0 1.6 1.3 2.9 2.9 2.9h16.3c1.6 0 2.9-1.3 2.9-2.9v-73.6c6.2-3.9 13.4-5.9 20.7-5.8 8.6 0 14 3.3 14 12.6v66.7c0 1.6 1.3 2.9 2.9 2.9h16.3c1.6 0 2.9-1.3 2.9-2.9l.1-66.5zm50.4 61.7c9.3 6.9 20.5 10.5 32 10.2 28.8 0 39.4-19.3 39.4-51.7s-10.7-51.7-39.4-51.7c-9.4 0-18.5 2.7-26.4 7.7V94.2c0-1.6-1.2-2.9-2.8-3h-16.6c-1.6 0-2.9 1.3-2.9 2.9v120.3c0 1.6 1.3 2.9 2.9 2.9h8.2c1 0 2-.5 2.5-1.4l3.1-6.5zm26.8-8.5c-7.5 0-14.8-2-21.3-5.8v-54.4c6.5-3.8 13.8-5.8 21.3-5.8 19.3 0 22.3 14.8 22.3 32.9s-2.8 33.1-22.3 33.1zM868 135.7c-2.5-.3-5.1-.5-7.7-.5-8.8-.4-17.5 1.7-25.3 5.9v73.2c0 1.6-1.3 2.9-2.9 2.9h-16.3c-1.6 0-2.9-1.3-2.9-2.9v-92.7c0-1.6 1.3-2.9 2.9-2.9h8.2c1 0 2 .5 2.5 1.4l2.9 6.5c8.9-6.8 19.9-10.4 31.2-10.2 2.6 0 5.2.2 7.7.6 1.4 0 2.7 2.4 2.7 4v11.8c0 1.6-1.3 2.9-2.9 2.9h-.2m56.7 36.1c-9.8 1.2-15.6 4.9-15.6 15.2 0 7.5 3.3 14.6 15.2 14.6 7.5.1 14.9-2.2 21.1-6.5v-25.5l-20.7 2.2zm26.1 37.6c-8.5 6.7-19 10.3-29.8 10.2-25.5 0-33.9-15.8-33.9-31.6 0-21.3 13.8-30.4 36.1-32.1l22.1-1.8v-4.9c0-10.1-4.7-14-19.3-14-9.2 0-18.3 1.5-26.9 4.5h-.9c-1.6 0-2.9-1.3-2.9-2.9v-13.1c0-1.2.7-2.4 1.9-2.8 9.8-3.3 20.1-5 30.5-4.9 32.3 0 39.8 14.2 39.8 35.1V214c0 1.6-1.3 2.9-2.9 2.9h-8.2c-1 0-2-.5-2.5-1.4l-3.1-6.1zM1063 197h.9c1.6 0 2.9 1.3 2.9 2.9V213c0 1.2-.7 2.3-1.8 2.7-8.1 2.9-16.7 4.3-25.4 4.1-34.9 0-45.7-20.9-45.7-51.7s10.7-51.7 45.7-51.7c8.6-.2 17.1 1.1 25.2 4 1.1.4 1.9 1.5 1.8 2.7v13.1c0 1.6-1.3 2.9-2.9 2.9h-.9c-7.1-2.2-14.6-3.3-22-3.1-19.1 0-24.7 13.1-24.7 32.2s5.5 32.1 24.7 32.1c7.5.1 14.9-1 22-3.3" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 315.89 315.89"><path fill="#fff" d="M0 157.74a157.95 157.95 0 11158 158.15A157.95 157.95 0 010 157.74zm154.74 54.09a155.41 155.41 0 01-36.5-3.29 27.92 27.92 0 01-19.94-16q-5.35-12.34-5.21-38.1a243 243 0 011.69-26.84q1.55-13 3.09-21.46l1.07-5.59a2 2 0 000-.49 3.2 3.2 0 00-2.65-3.17l-20.37-3.22h-.44a3.19 3.19 0 00-3.11 2.48c-.35 1.31-.56 2.27-1.17 5.38-1.16 6-2.24 11.85-3.43 20.38a264.17 264.17 0 00-2.3 27.94 145.24 145.24 0 000 19.57q.72 25.94 8.9 41.42t27.72 22.3q19.53 6.81 54.43 6.66h2.91q34.94.15 54.41-6.66t27.71-22.3q8.17-15.53 8.91-41.42a145.24 145.24 0 000-19.57 266.84 266.84 0 00-2.3-27.94c-1.2-8.44-2.27-14.26-3.44-20.38-.61-3.11-.81-4.07-1.16-5.38a3.21 3.21 0 00-3.12-2.48h-.52l-20.38 3.18a3.2 3.2 0 00-2.68 3.17 4 4 0 000 .49l1.08 5.59q1.55 8.48 3.12 21.46a245.68 245.68 0 011.65 26.84q.27 25.69-5.21 38.07a27.9 27.9 0 01-19.76 16.07 155.19 155.19 0 01-36.48 3.29z"/></svg>
|
||||
|
Before Width: | Height: | Size: 942 B |
@@ -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`
|
||||
<div id="background"></div>
|
||||
|
||||
<div id="logo">
|
||||
<img src="umbraco_logomark_white.svg" alt="Umbraco" />
|
||||
</div>
|
||||
|
||||
<div id="container">
|
||||
<uui-box id="box">
|
||||
<slot></slot>
|
||||
</uui-box>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<LoginResponse> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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`
|
||||
<b>Custom External Login Provider</b>
|
||||
<p>This is an example of a custom external login provider using the external login provider extension point</p>
|
||||
<uui-button label="My custom login provider" look="primary"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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`
|
||||
<b>Another Custom External Login Provider</b>
|
||||
<p>This is an example of another custom external login provider</p>
|
||||
<uui-form-layout-item>
|
||||
<uui-label id="emailLabel" for="email" slot="label" required>Email</uui-label>
|
||||
<uui-input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="Enter your email..."
|
||||
required
|
||||
required-message="Email is required"></uui-input>
|
||||
</uui-form-layout-item>
|
||||
<uui-button label="Custom login" look="primary"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<ManifestExternalLoginProvider> = [
|
||||
{
|
||||
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',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -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';
|
||||
@@ -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`
|
||||
<umb-auth-layout>
|
||||
<div class="uui-text">
|
||||
<h1 class="uui-h3">${this.#greeting}</h1>
|
||||
<uui-form>
|
||||
<form id="LoginForm" name="login" @submit="${this.#handleSubmit}">
|
||||
<uui-form-layout-item>
|
||||
<uui-label id="emailLabel" for="email" slot="label" required>Email</uui-label>
|
||||
<uui-input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
label="Email"
|
||||
required
|
||||
required-message="Email is required"></uui-input>
|
||||
</uui-form-layout-item>
|
||||
|
||||
<uui-form-layout-item>
|
||||
<uui-label id="passwordLabel" for="password" slot="label" required>Password</uui-label>
|
||||
<uui-input-password
|
||||
id="password"
|
||||
name="password"
|
||||
label="Password"
|
||||
required
|
||||
required-message="Password is required"></uui-input-password>
|
||||
</uui-form-layout-item>
|
||||
|
||||
${this.#authContext.supportsPersistLogin
|
||||
? html`<uui-form-layout-item>
|
||||
<uui-checkbox name="persist" label="Remember me">Remember me</uui-checkbox>
|
||||
</uui-form-layout-item>`
|
||||
: nothing}
|
||||
|
||||
<uui-form-layout-item>${this.#renderErrorMessage()}</uui-form-layout-item>
|
||||
|
||||
<uui-button
|
||||
type="submit"
|
||||
label="Login"
|
||||
look="primary"
|
||||
color="positive"
|
||||
state=${this._loginState}></uui-button>
|
||||
</form>
|
||||
</uui-form>
|
||||
</div>
|
||||
</umb-auth-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderErrorMessage() {
|
||||
if (!this._loginError || this._loginState !== 'failed') return nothing;
|
||||
|
||||
return html`<p class="text-danger">${this._loginError}</p>`;
|
||||
}
|
||||
|
||||
static styles: CSSResultGroup = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
#email,
|
||||
#password {
|
||||
width: 100%;
|
||||
}
|
||||
.text-danger {
|
||||
color: var(--uui-color-danger-standalone);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-login': UmbLoginElement;
|
||||
}
|
||||
}
|
||||
@@ -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`<umb-login></umb-login>`);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
export type LoginRequestModel = {
|
||||
username: string;
|
||||
password: string;
|
||||
persist: boolean;
|
||||
};
|
||||
|
||||
export interface IUmbAuthContext {
|
||||
login(data: LoginRequestModel): Promise<LoginResponse>;
|
||||
supportsPersistLogin: boolean;
|
||||
}
|
||||
|
||||
export type LoginResponse = {
|
||||
data?: string;
|
||||
error?: string;
|
||||
status: number;
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
/*
|
||||
interface ImportMetaEnv {
|
||||
}
|
||||
*/
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"declaration": false
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
@@ -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()],
|
||||
});
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user