Skip to content

Commit 434189e

Browse files
authored
V16: Upgrade Login dependencies to Umbraco 16 (#19433)
* build: updates login page to match Umbraco 16 * build(deps): bump heyapi to latest * chore: simplify logic
1 parent b4d5c8f commit 434189e

File tree

8 files changed

+1164
-1111
lines changed

8 files changed

+1164
-1111
lines changed

src/Umbraco.Web.UI.Login/package-lock.json

Lines changed: 893 additions & 847 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Umbraco.Web.UI.Login/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
"npm": ">=10.9"
1515
},
1616
"devDependencies": {
17-
"@hey-api/client-fetch": "^0.10.0",
18-
"@hey-api/openapi-ts": "^0.66.3",
19-
"@umbraco-cms/backoffice": "15.3.0",
17+
"@hey-api/client-fetch": "^0.10.2",
18+
"@hey-api/openapi-ts": "^0.67.6",
19+
"@umbraco-cms/backoffice": "16.0.0-rc3",
2020
"msw": "^2.7.0",
21-
"typescript": "^5.7.3",
22-
"vite": "^6.2.6",
21+
"typescript": "^5.8.3",
22+
"vite": "^6.3.5",
2323
"vite-tsconfig-paths": "^5.1.4"
2424
},
2525
"msw": {

src/Umbraco.Web.UI.Login/src/components/layouts/new-password-layout.element.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ export default class UmbNewPasswordLayoutElement extends UmbLitElement {
3434
super();
3535

3636
this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => {
37-
this._passwordConfiguration = authContext.passwordConfiguration;
3837
// Build a pattern
3938
let pattern = '';
39+
this._passwordConfiguration = authContext?.passwordConfiguration;
4040
if (this._passwordConfiguration?.requireDigit) {
4141
pattern += '(?=.*\\d)';
4242
}

src/Umbraco.Web.UI.Login/src/components/pages/login.page.element.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default class UmbLoginPageElement extends UmbLitElement {
3333

3434
this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => {
3535
this.#authContext = authContext;
36-
this.supportPersistLogin = authContext.supportsPersistLogin;
36+
this.supportPersistLogin = authContext?.supportsPersistLogin ?? false;
3737
});
3838
}
3939

Lines changed: 162 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,173 @@
1-
import type {UUIButtonState} from '@umbraco-cms/backoffice/external/uui';
2-
import {type CSSResultGroup, css, html, nothing, customElement, state} from '@umbraco-cms/backoffice/external/lit';
3-
import { UmbLitElement } from "@umbraco-cms/backoffice/lit-element";
1+
import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
2+
import { type CSSResultGroup, css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
44

55
import { UMB_AUTH_CONTEXT } from '../../contexts';
66

77
@customElement('umb-reset-password-page')
88
export default class UmbResetPasswordPageElement extends UmbLitElement {
9-
@state()
10-
resetCallState: UUIButtonState = undefined;
11-
12-
@state()
13-
error = '';
14-
15-
#handleResetSubmit = async (e: SubmitEvent) => {
16-
e.preventDefault();
17-
const form = e.target as HTMLFormElement;
18-
19-
if (!form) return;
20-
if (!form.checkValidity()) return;
21-
22-
const formData = new FormData(form);
23-
const username = formData.get('email') as string;
24-
25-
this.resetCallState = 'waiting';
26-
const authContext = await this.getContext(UMB_AUTH_CONTEXT);
27-
const response = await authContext.resetPassword(username);
28-
this.resetCallState = response.error ? 'failed' : 'success';
29-
this.error = response.error || '';
30-
};
31-
32-
#renderResetPage() {
33-
return html`
34-
<uui-form>
35-
<form id="LoginForm" name="login" @submit="${this.#handleResetSubmit}">
36-
<header id="header">
37-
<h1>
38-
<umb-localize key="auth_forgottenPassword">Forgotten password?</umb-localize>
39-
</h1>
40-
<span>
9+
@state()
10+
resetCallState: UUIButtonState = undefined;
11+
12+
@state()
13+
error = '';
14+
15+
#handleResetSubmit = async (e: SubmitEvent) => {
16+
e.preventDefault();
17+
const form = e.target as HTMLFormElement;
18+
19+
if (!form) return;
20+
if (!form.checkValidity()) return;
21+
22+
const formData = new FormData(form);
23+
const username = formData.get('email') as string;
24+
25+
this.resetCallState = 'waiting';
26+
const authContext = await this.getContext(UMB_AUTH_CONTEXT);
27+
if (!authContext) {
28+
this.resetCallState = 'failed';
29+
this.error = 'Authentication context not available.';
30+
return;
31+
}
32+
const response = await authContext.resetPassword(username);
33+
this.resetCallState = response.error ? 'failed' : 'success';
34+
this.error = response.error || '';
35+
};
36+
37+
#renderResetPage() {
38+
return html`
39+
<uui-form>
40+
<form id="LoginForm" name="login" @submit="${this.#handleResetSubmit}">
41+
<header id="header">
42+
<h1>
43+
<umb-localize key="auth_forgottenPassword">Forgotten password?</umb-localize>
44+
</h1>
45+
<span>
4146
<umb-localize key="auth_forgottenPasswordInstruction">
42-
An email will be sent to the address specified with a link to reset your password
43-
</umb-localize>
47+
An email will be sent to the address specified with a link to reset your password
48+
</umb-localize>
4449
</span>
45-
</header>
46-
47-
<uui-form-layout-item>
48-
<uui-label for="email" slot="label" required>
49-
<umb-localize key="auth_email">Email</umb-localize>
50-
</uui-label>
51-
<uui-input
52-
type="email"
53-
id="email"
54-
name="email"
55-
.label=${this.localize.term('auth_email')}
56-
required
57-
required-message=${this.localize.term('auth_required')}>
58-
</uui-input>
59-
</uui-form-layout-item>
60-
61-
${this.#renderErrorMessage()}
62-
63-
<uui-button
64-
type="submit"
65-
.label=${this.localize.term('auth_submit')}
66-
look="primary"
67-
color="default"
68-
.state=${this.resetCallState}></uui-button>
69-
</form>
70-
</uui-form>
71-
72-
<umb-back-to-login-button style="margin-top: var(--uui-size-space-6)"></umb-back-to-login-button>
73-
`;
74-
}
75-
76-
#renderErrorMessage() {
77-
if (!this.error || this.resetCallState !== 'failed') return nothing;
78-
79-
return html`<span class="text-danger">${this.error}</span>`;
80-
}
81-
82-
#renderConfirmationPage() {
83-
return html`
84-
<umb-confirmation-layout
85-
header=${this.localize.term('auth_forgottenPassword')}
86-
message=${this.localize.term('auth_requestPasswordResetConfirmation')}>
87-
</umb-confirmation-layout>
88-
`;
89-
}
90-
91-
render() {
92-
return this.resetCallState === 'success' ? this.#renderConfirmationPage() : this.#renderResetPage();
93-
}
94-
95-
static styles: CSSResultGroup = [
96-
css`
97-
#header {
98-
text-align: center;
99-
display: flex;
100-
flex-direction: column;
101-
gap: var(--uui-size-space-5);
102-
}
103-
104-
#header span {
105-
color: var(--uui-color-text-alt); /* TODO Change to uui color when uui gets a muted text variable */
106-
font-size: 14px;
107-
}
108-
109-
#header h1 {
110-
margin: 0;
111-
font-weight: 400;
112-
font-size: var(--header-secondary-font-size);
113-
color: var(--uui-color-interactive);
114-
line-height: 1.2;
115-
}
116-
117-
form {
118-
display: flex;
119-
flex-direction: column;
120-
gap: var(--uui-size-layout-2);
121-
}
122-
123-
uui-form-layout-item {
124-
margin: 0;
125-
}
126-
127-
uui-input,
128-
uui-input-password {
129-
width: 100%;
130-
height: var(--input-height);
131-
border-radius: var(--uui-border-radius);
132-
}
133-
134-
uui-input {
135-
width: 100%;
136-
}
137-
138-
uui-button {
139-
width: 100%;
140-
--uui-button-padding-top-factor: 1.5;
141-
--uui-button-padding-bottom-factor: 1.5;
142-
}
143-
144-
#resend {
145-
display: inline-flex;
146-
font-size: 14px;
147-
align-self: center;
148-
gap: var(--uui-size-space-1);
149-
}
150-
151-
#resend a {
152-
color: var(--uui-color-selected);
153-
font-weight: 600;
154-
text-decoration: none;
155-
}
156-
157-
#resend a:hover {
158-
color: var(--uui-color-interactive-emphasis);
159-
}
160-
`,
161-
];
50+
</header>
51+
52+
<uui-form-layout-item>
53+
<uui-label for="email" slot="label" required>
54+
<umb-localize key="auth_email">Email</umb-localize>
55+
</uui-label>
56+
<uui-input
57+
type="email"
58+
id="email"
59+
name="email"
60+
.label=${this.localize.term('auth_email')}
61+
required
62+
required-message=${this.localize.term('auth_required')}>
63+
</uui-input>
64+
</uui-form-layout-item>
65+
66+
${this.#renderErrorMessage()}
67+
68+
<uui-button
69+
type="submit"
70+
.label=${this.localize.term('auth_submit')}
71+
look="primary"
72+
color="default"
73+
.state=${this.resetCallState}></uui-button>
74+
</form>
75+
</uui-form>
76+
77+
<umb-back-to-login-button style="margin-top: var(--uui-size-space-6)"></umb-back-to-login-button>
78+
`;
79+
}
80+
81+
#renderErrorMessage() {
82+
if (!this.error || this.resetCallState !== 'failed') return nothing;
83+
84+
return html`<span class="text-danger">${this.error}</span>`;
85+
}
86+
87+
#renderConfirmationPage() {
88+
return html`
89+
<umb-confirmation-layout
90+
header=${this.localize.term('auth_forgottenPassword')}
91+
message=${this.localize.term('auth_requestPasswordResetConfirmation')}>
92+
</umb-confirmation-layout>
93+
`;
94+
}
95+
96+
render() {
97+
return this.resetCallState === 'success' ? this.#renderConfirmationPage() : this.#renderResetPage();
98+
}
99+
100+
static styles: CSSResultGroup = [
101+
css`
102+
#header {
103+
text-align: center;
104+
display: flex;
105+
flex-direction: column;
106+
gap: var(--uui-size-space-5);
107+
}
108+
109+
#header span {
110+
color: var(--uui-color-text-alt); /* TODO Change to uui color when uui gets a muted text variable */
111+
font-size: 14px;
112+
}
113+
114+
#header h1 {
115+
margin: 0;
116+
font-weight: 400;
117+
font-size: var(--header-secondary-font-size);
118+
color: var(--uui-color-interactive);
119+
line-height: 1.2;
120+
}
121+
122+
form {
123+
display: flex;
124+
flex-direction: column;
125+
gap: var(--uui-size-layout-2);
126+
}
127+
128+
uui-form-layout-item {
129+
margin: 0;
130+
}
131+
132+
uui-input,
133+
uui-input-password {
134+
width: 100%;
135+
height: var(--input-height);
136+
border-radius: var(--uui-border-radius);
137+
}
138+
139+
uui-input {
140+
width: 100%;
141+
}
142+
143+
uui-button {
144+
width: 100%;
145+
--uui-button-padding-top-factor: 1.5;
146+
--uui-button-padding-bottom-factor: 1.5;
147+
}
148+
149+
#resend {
150+
display: inline-flex;
151+
font-size: 14px;
152+
align-self: center;
153+
gap: var(--uui-size-space-1);
154+
}
155+
156+
#resend a {
157+
color: var(--uui-color-selected);
158+
font-weight: 600;
159+
text-decoration: none;
160+
}
161+
162+
#resend a:hover {
163+
color: var(--uui-color-interactive-emphasis);
164+
}
165+
`,
166+
];
162167
}
163168

164169
declare global {
165-
interface HTMLElementTagNameMap {
166-
'umb-reset-password-page': UmbResetPasswordPageElement;
167-
}
170+
interface HTMLElementTagNameMap {
171+
'umb-reset-password-page': UmbResetPasswordPageElement;
172+
}
168173
}

0 commit comments

Comments
 (0)