@things-factory/auth-ui 8.0.0-alpha.29 → 8.0.0-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/abstract-auth-page.ts +10 -10
- package/client/components/abstract-password-reset.ts +5 -3
- package/client/components/abstract-sign.ts +13 -13
- package/client/components/contact-us.ts +11 -8
- package/client/components/create-user.ts +27 -5
- package/client/components/invite-user.ts +14 -6
- package/client/components/profile-component.ts +64 -4
- package/client/entries/auth/forgot-password.ts +11 -2
- package/client/entries/auth/signup.ts +13 -7
- package/client/index.ts +1 -1
- package/client/pages/user/user-management.ts +1 -1
- package/dist-client/components/abstract-auth-page.js +10 -10
- package/dist-client/components/abstract-auth-page.js.map +1 -1
- package/dist-client/components/abstract-password-reset.js +5 -3
- package/dist-client/components/abstract-password-reset.js.map +1 -1
- package/dist-client/components/abstract-sign.js +12 -11
- package/dist-client/components/abstract-sign.js.map +1 -1
- package/dist-client/components/contact-us.d.ts +1 -1
- package/dist-client/components/contact-us.js +10 -7
- package/dist-client/components/contact-us.js.map +1 -1
- package/dist-client/components/create-user.js +28 -5
- package/dist-client/components/create-user.js.map +1 -1
- package/dist-client/components/invite-user.js +15 -7
- package/dist-client/components/invite-user.js.map +1 -1
- package/dist-client/components/profile-component.d.ts +5 -1
- package/dist-client/components/profile-component.js +64 -4
- package/dist-client/components/profile-component.js.map +1 -1
- package/dist-client/entries/auth/forgot-password.js +11 -2
- package/dist-client/entries/auth/forgot-password.js.map +1 -1
- package/dist-client/entries/auth/signup.js +13 -7
- package/dist-client/entries/auth/signup.js.map +1 -1
- package/dist-client/index.js +1 -1
- package/dist-client/index.js.map +1 -1
- package/dist-client/pages/user/user-management.d.ts +5 -1
- package/dist-client/pages/user/user-management.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/translations/en.json +6 -1
- package/translations/ja.json +6 -1
- package/translations/ko.json +6 -1
- package/translations/ms.json +6 -1
- package/translations/zh.json +6 -1
|
@@ -176,22 +176,22 @@ export abstract class AbstractAuthPage extends localize(i18next)(LitElement) {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
get formfields() {
|
|
179
|
-
const
|
|
180
|
-
// .validationMessage=${String(i18next.t('text.invalid-
|
|
179
|
+
const username = this.data?.username || ''
|
|
180
|
+
// .validationMessage=${String(i18next.t('text.invalid-username'))}
|
|
181
181
|
|
|
182
182
|
return html`
|
|
183
183
|
<input id="redirectTo" type="hidden" name="redirectTo" .value=${this.redirectTo || '/'} />
|
|
184
184
|
|
|
185
185
|
<div class="field">
|
|
186
186
|
<md-filled-text-field
|
|
187
|
-
name="
|
|
188
|
-
type="
|
|
189
|
-
label=${String(i18next.t('field.email'))}
|
|
187
|
+
name="username"
|
|
188
|
+
type="text"
|
|
189
|
+
label=${String(i18next.t('field.user-id or email'))}
|
|
190
190
|
required
|
|
191
|
-
.value=${
|
|
191
|
+
.value=${username}
|
|
192
192
|
autocomplete="off"
|
|
193
193
|
autocapitalize="off"
|
|
194
|
-
><md-icon slot="leading-icon">
|
|
194
|
+
><md-icon slot="leading-icon">id_card</md-icon></md-filled-text-field
|
|
195
195
|
>
|
|
196
196
|
</div>
|
|
197
197
|
<div class="field">
|
|
@@ -201,11 +201,11 @@ export abstract class AbstractAuthPage extends localize(i18next)(LitElement) {
|
|
|
201
201
|
label=${String(i18next.t('field.password'))}
|
|
202
202
|
autocomplete="off"
|
|
203
203
|
required
|
|
204
|
-
><md-icon slot="leading-icon">
|
|
204
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
205
205
|
>
|
|
206
206
|
</div>
|
|
207
207
|
|
|
208
|
-
<md-elevated-button class="ui" type="
|
|
208
|
+
<md-elevated-button class="ui" type="button" raised @click=${e => this._onSubmit(e)}>
|
|
209
209
|
<ox-i18n msgid="field.${this.pageName}"> </ox-i18n>
|
|
210
210
|
</md-elevated-button>
|
|
211
211
|
`
|
|
@@ -235,7 +235,7 @@ export abstract class AbstractAuthPage extends localize(i18next)(LitElement) {
|
|
|
235
235
|
sso => html`
|
|
236
236
|
<a class="link" href=${sso.link}>
|
|
237
237
|
<md-text-button>
|
|
238
|
-
<md-icon slot="icon">
|
|
238
|
+
<md-icon slot="icon">id_card</md-icon>
|
|
239
239
|
${i18next.t('label.signin with', { title: sso.title })}
|
|
240
240
|
</md-text-button>
|
|
241
241
|
</a>
|
|
@@ -91,7 +91,8 @@ export abstract class AbstractPasswordReset extends AbstractAuthPage {
|
|
|
91
91
|
this.confirmPass.setAttribute('pattern', val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '[$&]'))
|
|
92
92
|
}}
|
|
93
93
|
required
|
|
94
|
-
|
|
94
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
95
|
+
>
|
|
95
96
|
</div>
|
|
96
97
|
|
|
97
98
|
<div class="field">
|
|
@@ -102,10 +103,11 @@ export abstract class AbstractPasswordReset extends AbstractAuthPage {
|
|
|
102
103
|
label=${String(i18next.t('field.confirm password'))}
|
|
103
104
|
autocomplete="off"
|
|
104
105
|
required
|
|
105
|
-
|
|
106
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
107
|
+
>
|
|
106
108
|
</div>
|
|
107
109
|
|
|
108
|
-
<md-elevated-button id="submit-button" type="
|
|
110
|
+
<md-elevated-button id="submit-button" type="button" @click=${e => this._onSubmit(e)}>
|
|
109
111
|
<ox-i18n msgid="${this.submitButtonLabel}"></ox-i18n>
|
|
110
112
|
</md-elevated-button>
|
|
111
113
|
|
|
@@ -44,7 +44,7 @@ export abstract class AbstractSign extends AbstractAuthPage {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
get formfields() {
|
|
47
|
-
const
|
|
47
|
+
const username = this.data?.username || ''
|
|
48
48
|
const autocompletable = this.autocompletable
|
|
49
49
|
|
|
50
50
|
return html`
|
|
@@ -52,22 +52,23 @@ export abstract class AbstractSign extends AbstractAuthPage {
|
|
|
52
52
|
|
|
53
53
|
<div class="field">
|
|
54
54
|
<md-filled-text-field
|
|
55
|
-
name="
|
|
56
|
-
type="
|
|
57
|
-
label=${String(i18next.t('field.email'))}
|
|
55
|
+
name="username"
|
|
56
|
+
type="text"
|
|
57
|
+
label=${String(i18next.t('field.user-id or email'))}
|
|
58
58
|
required
|
|
59
|
-
.value=${
|
|
60
|
-
autocomplete=${autocompletable ?
|
|
59
|
+
.value=${username}
|
|
60
|
+
autocomplete=${autocompletable ? 'username' : 'off'}
|
|
61
61
|
autocapitalize="off"
|
|
62
|
+
pattern="^(?:[A-Za-z0-9]*|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,})$"
|
|
62
63
|
@input=${(e: Event) => {
|
|
63
64
|
const target = e.target as HTMLInputElement
|
|
64
65
|
if (target.validity.typeMismatch) {
|
|
65
|
-
target.setCustomValidity(i18next.t('text.invalid-
|
|
66
|
+
target.setCustomValidity(i18next.t('text.invalid-username'))
|
|
66
67
|
} else {
|
|
67
68
|
target.setCustomValidity('')
|
|
68
69
|
}
|
|
69
70
|
}}
|
|
70
|
-
><md-icon slot="leading-icon">
|
|
71
|
+
><md-icon slot="leading-icon">id_card</md-icon></md-filled-text-field
|
|
71
72
|
>
|
|
72
73
|
</div>
|
|
73
74
|
<div class="field">
|
|
@@ -75,14 +76,14 @@ export abstract class AbstractSign extends AbstractAuthPage {
|
|
|
75
76
|
name="password"
|
|
76
77
|
type="password"
|
|
77
78
|
label=${String(i18next.t('field.password'))}
|
|
78
|
-
autocomplete=${autocompletable ?
|
|
79
|
+
autocomplete=${autocompletable ? 'current-password' : 'off'}
|
|
79
80
|
required
|
|
80
|
-
><md-icon slot="leading-icon">
|
|
81
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
81
82
|
>
|
|
82
83
|
</div>
|
|
83
84
|
|
|
84
85
|
<div class="submit-buttons-container">
|
|
85
|
-
<md-elevated-button class="submit-button" type="
|
|
86
|
+
<md-elevated-button class="submit-button" type="button" raised @click=${e => this._onSubmit(e)}>
|
|
86
87
|
<ox-i18n msgid="field.${this.pageName}"> </ox-i18n>
|
|
87
88
|
</md-elevated-button>
|
|
88
89
|
${isAvailableWebauthn
|
|
@@ -106,7 +107,7 @@ export abstract class AbstractSign extends AbstractAuthPage {
|
|
|
106
107
|
|
|
107
108
|
if (verification.verified) {
|
|
108
109
|
const { redirectURL } = verification
|
|
109
|
-
|
|
110
|
+
|
|
110
111
|
if (redirectURL) {
|
|
111
112
|
window.location.href = redirectURL
|
|
112
113
|
}
|
|
@@ -116,7 +117,6 @@ export abstract class AbstractSign extends AbstractAuthPage {
|
|
|
116
117
|
message: verification.message
|
|
117
118
|
})
|
|
118
119
|
}
|
|
119
|
-
|
|
120
120
|
} catch (error) {
|
|
121
121
|
notify({
|
|
122
122
|
level: 'error',
|
|
@@ -33,22 +33,23 @@ export class ContactUs extends localize(i18next)(LitElement) {
|
|
|
33
33
|
]
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
@query('#dialog') dialog!: HTMLElement & {
|
|
36
|
+
@query('#dialog') dialog!: HTMLElement & { show: () => void }
|
|
37
37
|
@query('#subject-input') subjectInput!: HTMLInputElement
|
|
38
38
|
@query('#sender-input') senderInput!: HTMLInputElement
|
|
39
39
|
@query('#content-input') contentInput!: HTMLInputElement
|
|
40
40
|
|
|
41
41
|
render() {
|
|
42
42
|
return html`
|
|
43
|
-
<md-elevated-button @click=${e =>
|
|
43
|
+
<md-elevated-button @click=${e => this.dialog.show()}>${i18next.t('button.need help')}</md-elevated-button>
|
|
44
44
|
|
|
45
45
|
<md-dialog id="dialog" heading=${i18next.t('title.need help')}>
|
|
46
|
-
<form action="" method="
|
|
46
|
+
<form action="" method="post">
|
|
47
47
|
<input id="subject-input" name="subject" type="hidden" />
|
|
48
48
|
<input id="sender-input" name="sender" type="hidden" />
|
|
49
49
|
<input id="content-input" name="content" type="hidden" />
|
|
50
50
|
</form>
|
|
51
|
-
|
|
51
|
+
|
|
52
|
+
<div id="input-form" slot="content">
|
|
52
53
|
<md-filled-text-field
|
|
53
54
|
type="text"
|
|
54
55
|
label=${i18next.t('label.subject')}
|
|
@@ -59,6 +60,7 @@ export class ContactUs extends localize(i18next)(LitElement) {
|
|
|
59
60
|
this.subjectInput.value = val
|
|
60
61
|
}}
|
|
61
62
|
></md-filled-text-field>
|
|
63
|
+
|
|
62
64
|
<md-filled-text-field
|
|
63
65
|
type="text"
|
|
64
66
|
name="sender"
|
|
@@ -69,6 +71,7 @@ export class ContactUs extends localize(i18next)(LitElement) {
|
|
|
69
71
|
this.senderInput.value = val
|
|
70
72
|
}}
|
|
71
73
|
></md-filled-text-field>
|
|
74
|
+
|
|
72
75
|
<md-filled-text-field
|
|
73
76
|
name="content"
|
|
74
77
|
type="textarea"
|
|
@@ -80,11 +83,11 @@ export class ContactUs extends localize(i18next)(LitElement) {
|
|
|
80
83
|
this.contentInput.value = val
|
|
81
84
|
}}
|
|
82
85
|
></md-filled-text-field>
|
|
86
|
+
|
|
87
|
+
<md-elevated-button slot="primaryAction" type="button" @click=${e => this._submit(e)}
|
|
88
|
+
>${i18next.t('button.submit')}</md-elevated-button
|
|
89
|
+
>
|
|
83
90
|
</div>
|
|
84
|
-
<md-elevated-button slot="primaryAction" type="submit" @click=${e => this._submit(e)}
|
|
85
|
-
>${i18next.t('button.submit')}</md-elevated-button
|
|
86
|
-
>
|
|
87
|
-
<md-text-button slot="secondaryAction" dialogAction="cancel">${i18next.t('button.cancel')}</md-text-button>
|
|
88
91
|
</md-dialog>
|
|
89
92
|
`
|
|
90
93
|
}
|
|
@@ -6,6 +6,10 @@ import { customElement, query } from 'lit/decorators.js'
|
|
|
6
6
|
|
|
7
7
|
import { i18next } from '@operato/i18n'
|
|
8
8
|
|
|
9
|
+
function capitalize(str) {
|
|
10
|
+
return str ? str.charAt(0).toUpperCase() + str.slice(1) : ''
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
@customElement('create-user')
|
|
10
14
|
class CreateUser extends LitElement {
|
|
11
15
|
static styles = css`
|
|
@@ -18,7 +22,7 @@ class CreateUser extends LitElement {
|
|
|
18
22
|
box-shadow: var(--box-shadow);
|
|
19
23
|
|
|
20
24
|
display: grid;
|
|
21
|
-
grid-template-columns: 1fr 2fr auto;
|
|
25
|
+
grid-template-columns: 1fr 2fr 2fr auto;
|
|
22
26
|
gap: 5px 15px;
|
|
23
27
|
clear: both;
|
|
24
28
|
max-width: var(--input-container-max-width);
|
|
@@ -44,26 +48,42 @@ class CreateUser extends LitElement {
|
|
|
44
48
|
`
|
|
45
49
|
|
|
46
50
|
@query('[name=name]') nameInput!: HTMLInputElement
|
|
51
|
+
@query('[name=username]') usernameInput!: HTMLInputElement
|
|
47
52
|
@query('[name=email]') emailInput!: HTMLInputElement
|
|
48
53
|
|
|
49
54
|
render() {
|
|
50
55
|
return html`
|
|
56
|
+
<md-filled-text-field
|
|
57
|
+
type="text"
|
|
58
|
+
name="username"
|
|
59
|
+
label=${capitalize(i18next.t('label.user-id'))}
|
|
60
|
+
pattern="^(?:[A-Za-z0-9]*|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,})$"
|
|
61
|
+
><md-icon slot="leading-icon">badge</md-icon></md-filled-text-field
|
|
62
|
+
>
|
|
63
|
+
|
|
51
64
|
<md-filled-text-field
|
|
52
65
|
type="text"
|
|
53
66
|
name="name"
|
|
54
|
-
label=${
|
|
55
|
-
|
|
67
|
+
label=${capitalize(i18next.t('label.x name', { x: i18next.t('label.user') }))}
|
|
68
|
+
><md-icon slot="leading-icon">id_card</md-icon></md-filled-text-field
|
|
69
|
+
>
|
|
56
70
|
|
|
57
|
-
<md-filled-text-field type="email" name="email" label=${
|
|
71
|
+
<md-filled-text-field type="email" name="email" label=${capitalize(i18next.t('field.email'))}
|
|
72
|
+
><md-icon slot="leading-icon">mail</md-icon></md-filled-text-field
|
|
73
|
+
>
|
|
58
74
|
|
|
59
75
|
<md-outlined-button @click=${this.onCreateUser.bind(this)}
|
|
60
|
-
>${
|
|
76
|
+
>${capitalize(i18next.t('button.create'))}</md-outlined-button
|
|
61
77
|
>
|
|
62
78
|
`
|
|
63
79
|
}
|
|
64
80
|
|
|
65
81
|
async onCreateUser() {
|
|
66
82
|
try {
|
|
83
|
+
if (!this.usernameInput.value) {
|
|
84
|
+
throw new Error(i18next.t('error.value is empty', { value: 'name' }))
|
|
85
|
+
}
|
|
86
|
+
|
|
67
87
|
if (!this.emailInput.checkValidity()) {
|
|
68
88
|
throw new Error(i18next.t('error.not valid pattern of type', { type: 'e-mail' }))
|
|
69
89
|
}
|
|
@@ -73,12 +93,14 @@ class CreateUser extends LitElement {
|
|
|
73
93
|
}
|
|
74
94
|
|
|
75
95
|
const user = {
|
|
96
|
+
username: this.usernameInput.value.trim(),
|
|
76
97
|
name: this.nameInput.value.trim(),
|
|
77
98
|
email: this.emailInput.value.trim()
|
|
78
99
|
}
|
|
79
100
|
|
|
80
101
|
await this.dispatchEvent(new CustomEvent('create-user', { detail: user }))
|
|
81
102
|
|
|
103
|
+
this.usernameInput.value = ''
|
|
82
104
|
this.nameInput.value = ''
|
|
83
105
|
this.emailInput.value = ''
|
|
84
106
|
} catch (e: any) {
|
|
@@ -32,11 +32,19 @@ class InviteUser extends localize(i18next)(LitElement) {
|
|
|
32
32
|
}
|
|
33
33
|
`
|
|
34
34
|
|
|
35
|
-
@query('input[name=
|
|
35
|
+
@query('input[name=username]') userIdInput!: HTMLInputElement
|
|
36
36
|
|
|
37
37
|
render() {
|
|
38
38
|
return html`
|
|
39
|
-
<input
|
|
39
|
+
<input
|
|
40
|
+
name="username"
|
|
41
|
+
type="text"
|
|
42
|
+
required
|
|
43
|
+
name="username"
|
|
44
|
+
autocapitalize="off"
|
|
45
|
+
placeholder=${String(i18next.t('text.user invitation prompt'))}
|
|
46
|
+
pattern="^(?:[A-Za-z0-9]*|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,})$"
|
|
47
|
+
/>
|
|
40
48
|
<md-outlined-button @click=${this.invite.bind(this)}>
|
|
41
49
|
<md-icon slot="icon">group_add</md-icon>${String(i18next.t('label.invite user'))}
|
|
42
50
|
</md-outlined-button>
|
|
@@ -45,8 +53,8 @@ class InviteUser extends localize(i18next)(LitElement) {
|
|
|
45
53
|
|
|
46
54
|
async invite() {
|
|
47
55
|
try {
|
|
48
|
-
if (!this.
|
|
49
|
-
throw new Error(i18next.t('error.not valid pattern of type', { type: '
|
|
56
|
+
if (!this.userIdInput.checkValidity()) {
|
|
57
|
+
throw new Error(i18next.t('error.not valid pattern of type', { type: 'user-id or email' }))
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
if (
|
|
@@ -57,7 +65,7 @@ class InviteUser extends localize(i18next)(LitElement) {
|
|
|
57
65
|
cancelButton: { text: i18next.t('button.cancel') }
|
|
58
66
|
})
|
|
59
67
|
) {
|
|
60
|
-
await this.inviteUser(this.
|
|
68
|
+
await this.inviteUser(this.userIdInput.value)
|
|
61
69
|
|
|
62
70
|
this.dispatchEvent(new CustomEvent('invitationCompleted'))
|
|
63
71
|
}
|
|
@@ -90,7 +98,7 @@ class InviteUser extends localize(i18next)(LitElement) {
|
|
|
90
98
|
confirmButton: { text: i18next.t('button.confirm') }
|
|
91
99
|
})
|
|
92
100
|
|
|
93
|
-
this.
|
|
101
|
+
this.userIdInput.value = ''
|
|
94
102
|
}
|
|
95
103
|
}
|
|
96
104
|
}
|
|
@@ -111,7 +111,7 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
|
|
|
111
111
|
`
|
|
112
112
|
]
|
|
113
113
|
|
|
114
|
-
@property({ type: String })
|
|
114
|
+
@property({ type: String }) username?: string
|
|
115
115
|
@property({ type: String }) email?: string
|
|
116
116
|
@property({ type: String }) name?: string
|
|
117
117
|
|
|
@@ -128,7 +128,9 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
|
|
|
128
128
|
looseCharacterLength?: number
|
|
129
129
|
} = {}
|
|
130
130
|
|
|
131
|
+
@query('#username') usernameEl!: HTMLInputElement
|
|
131
132
|
@query('#name') nameEl!: HTMLInputElement
|
|
133
|
+
@query('#email') emailEl!: HTMLInputElement
|
|
132
134
|
@query('#locale') localeEl!: HTMLInputElement
|
|
133
135
|
|
|
134
136
|
async connectedCallback(): Promise<void> {
|
|
@@ -167,11 +169,11 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
|
|
|
167
169
|
|
|
168
170
|
setCredential(credential) {
|
|
169
171
|
if (credential) {
|
|
170
|
-
this.
|
|
172
|
+
this.username = credential.username
|
|
171
173
|
this.name = credential.name
|
|
172
174
|
this.email = credential.email
|
|
173
175
|
} else {
|
|
174
|
-
this.
|
|
176
|
+
this.username = ''
|
|
175
177
|
this.name = ''
|
|
176
178
|
this.email = ''
|
|
177
179
|
}
|
|
@@ -180,13 +182,23 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
|
|
|
180
182
|
render() {
|
|
181
183
|
return html`
|
|
182
184
|
<div class="wrap">
|
|
183
|
-
<div class="user">${this.
|
|
185
|
+
<div class="user">${this.username || ''}</div>
|
|
186
|
+
|
|
187
|
+
<label for="username"><ox-i18n slot="title" msgid="label.user-id"></ox-i18n></label>
|
|
188
|
+
<input id="username" @change=${e => this.onUsernameChanged(e.target.value)} .value=${this.username || ''} />
|
|
189
|
+
|
|
190
|
+
<hr />
|
|
184
191
|
|
|
185
192
|
<label for="name"><ox-i18n slot="title" msgid="label.name"></ox-i18n></label>
|
|
186
193
|
<input id="name" @change=${e => this.onNameChanged(e.target.value)} .value=${this.name || ''} />
|
|
187
194
|
|
|
188
195
|
<hr />
|
|
189
196
|
|
|
197
|
+
<label for="email"><ox-i18n slot="title" msgid="label.email"></ox-i18n></label>
|
|
198
|
+
<input id="email" type="email" @change=${e => this.onEmailChanged(e.target.value)} .value=${this.email || ''} />
|
|
199
|
+
|
|
200
|
+
<hr />
|
|
201
|
+
|
|
190
202
|
<label for="locale"><ox-i18n slot="title" msgid="label.language"></ox-i18n></label>
|
|
191
203
|
<ox-i18n-selector
|
|
192
204
|
id="locale"
|
|
@@ -223,6 +235,30 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
|
|
|
223
235
|
`
|
|
224
236
|
}
|
|
225
237
|
|
|
238
|
+
async onUsernameChanged(username) {
|
|
239
|
+
if (!username) return
|
|
240
|
+
|
|
241
|
+
var oldUsername = this.username
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
const message = await auth.updateProfile({
|
|
245
|
+
username
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
notify({
|
|
249
|
+
level: 'info',
|
|
250
|
+
message
|
|
251
|
+
})
|
|
252
|
+
} catch (e: any) {
|
|
253
|
+
this.usernameEl.value = oldUsername || ''
|
|
254
|
+
|
|
255
|
+
notify({
|
|
256
|
+
level: 'error',
|
|
257
|
+
message: 'message' in e ? e.message : e
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
226
262
|
async onNameChanged(name) {
|
|
227
263
|
if (!name) return
|
|
228
264
|
|
|
@@ -247,6 +283,30 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
|
|
|
247
283
|
}
|
|
248
284
|
}
|
|
249
285
|
|
|
286
|
+
async onEmailChanged(email) {
|
|
287
|
+
if (!email) return
|
|
288
|
+
|
|
289
|
+
var oldEmail = this.email
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
const message = await auth.updateProfile({
|
|
293
|
+
email
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
notify({
|
|
297
|
+
level: 'info',
|
|
298
|
+
message
|
|
299
|
+
})
|
|
300
|
+
} catch (e: any) {
|
|
301
|
+
this.emailEl.value = oldEmail || ''
|
|
302
|
+
|
|
303
|
+
notify({
|
|
304
|
+
level: 'error',
|
|
305
|
+
message: 'message' in e ? e.message : e
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
250
310
|
async onLocaleChanged(value) {
|
|
251
311
|
if (!value) return
|
|
252
312
|
|
|
@@ -43,9 +43,18 @@ export class ForgotPassword extends AbstractAuthPage {
|
|
|
43
43
|
target.setCustomValidity('')
|
|
44
44
|
}
|
|
45
45
|
}}
|
|
46
|
-
|
|
46
|
+
><md-icon slot="leading-icon">mail</md-icon></md-filled-text-field
|
|
47
|
+
>
|
|
47
48
|
</div>
|
|
48
|
-
<md-elevated-button
|
|
49
|
+
<md-elevated-button
|
|
50
|
+
id="submit-button"
|
|
51
|
+
class="ui button"
|
|
52
|
+
type="button"
|
|
53
|
+
@click=${e => {
|
|
54
|
+
this._onSubmit(e)
|
|
55
|
+
return false
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
49
58
|
<ox-i18n msgid="button.submit"></ox-i18n>
|
|
50
59
|
</md-elevated-button>
|
|
51
60
|
`
|
|
@@ -24,7 +24,7 @@ export class AuthSignup extends AbstractSign {
|
|
|
24
24
|
@query('#confirm-password') confirmPass!: HTMLInputElement
|
|
25
25
|
|
|
26
26
|
get formfields() {
|
|
27
|
-
const { name = '', email = '' } = this.data || {}
|
|
27
|
+
const { username = '', name = '', email = '' } = this.data || {}
|
|
28
28
|
|
|
29
29
|
// .validationMessage=${this.passwordHelp || ''}
|
|
30
30
|
// .validationMessage=${String(i18next.t('text.passwords do not match'))}
|
|
@@ -32,12 +32,18 @@ export class AuthSignup extends AbstractSign {
|
|
|
32
32
|
return html`
|
|
33
33
|
<div class="field">
|
|
34
34
|
<md-filled-text-field
|
|
35
|
-
name="
|
|
35
|
+
name="username"
|
|
36
36
|
type="text"
|
|
37
|
-
label=${String(i18next.t('field.
|
|
38
|
-
.value=${
|
|
37
|
+
label=${String(i18next.t('field.username'))}
|
|
38
|
+
.value=${username}
|
|
39
39
|
required
|
|
40
|
-
|
|
40
|
+
><md-icon slot="leading-icon">badge</md-icon></md-filled-text-field
|
|
41
|
+
>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="field">
|
|
44
|
+
<md-filled-text-field name="name" type="text" label=${String(i18next.t('field.name'))} .value=${name} required
|
|
45
|
+
><md-icon slot="leading-icon">id_card</md-icon></md-filled-text-field
|
|
46
|
+
>
|
|
41
47
|
</div>
|
|
42
48
|
<div class="field">
|
|
43
49
|
<md-filled-text-field
|
|
@@ -73,7 +79,7 @@ export class AuthSignup extends AbstractSign {
|
|
|
73
79
|
this.confirmPass.setAttribute('pattern', val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '[$&]'))
|
|
74
80
|
}}
|
|
75
81
|
>
|
|
76
|
-
></md-filled-text-field
|
|
82
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
77
83
|
>
|
|
78
84
|
</div>
|
|
79
85
|
<div class="field">
|
|
@@ -85,7 +91,7 @@ export class AuthSignup extends AbstractSign {
|
|
|
85
91
|
label=${String(i18next.t('field.confirm password'))}
|
|
86
92
|
required
|
|
87
93
|
>
|
|
88
|
-
></md-filled-text-field
|
|
94
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
89
95
|
>
|
|
90
96
|
</div>
|
|
91
97
|
<md-elevated-button class="ui button" @click=${e => this._onSubmit(e)}>
|
package/client/index.ts
CHANGED
|
@@ -87,7 +87,7 @@ export async function setAuthManagementMenus(options?: any) {
|
|
|
87
87
|
store.dispatch({
|
|
88
88
|
type: ADD_MORENDA,
|
|
89
89
|
morenda: {
|
|
90
|
-
icon: html` <md-icon>
|
|
90
|
+
icon: html` <md-icon>id_card</md-icon> `,
|
|
91
91
|
name: html` <ox-i18n msgid="text.auth-provider management"></ox-i18n> `,
|
|
92
92
|
action: () => {
|
|
93
93
|
navigate('auth-providers')
|
|
@@ -186,7 +186,7 @@ export class UserManagement extends localize(i18next)(PageView) {
|
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
async createUser(user) {
|
|
189
|
+
async createUser(user: { username: string; name: string; email: string }) {
|
|
190
190
|
if (
|
|
191
191
|
await OxPrompt.open({
|
|
192
192
|
title: i18next.t('text.are_you_sure'),
|
|
@@ -99,21 +99,21 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
|
|
|
99
99
|
}
|
|
100
100
|
get formfields() {
|
|
101
101
|
var _a;
|
|
102
|
-
const
|
|
103
|
-
// .validationMessage=${String(i18next.t('text.invalid-
|
|
102
|
+
const username = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.username) || '';
|
|
103
|
+
// .validationMessage=${String(i18next.t('text.invalid-username'))}
|
|
104
104
|
return html `
|
|
105
105
|
<input id="redirectTo" type="hidden" name="redirectTo" .value=${this.redirectTo || '/'} />
|
|
106
106
|
|
|
107
107
|
<div class="field">
|
|
108
108
|
<md-filled-text-field
|
|
109
|
-
name="
|
|
110
|
-
type="
|
|
111
|
-
label=${String(i18next.t('field.email'))}
|
|
109
|
+
name="username"
|
|
110
|
+
type="text"
|
|
111
|
+
label=${String(i18next.t('field.user-id or email'))}
|
|
112
112
|
required
|
|
113
|
-
.value=${
|
|
113
|
+
.value=${username}
|
|
114
114
|
autocomplete="off"
|
|
115
115
|
autocapitalize="off"
|
|
116
|
-
><md-icon slot="leading-icon">
|
|
116
|
+
><md-icon slot="leading-icon">id_card</md-icon></md-filled-text-field
|
|
117
117
|
>
|
|
118
118
|
</div>
|
|
119
119
|
<div class="field">
|
|
@@ -123,11 +123,11 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
|
|
|
123
123
|
label=${String(i18next.t('field.password'))}
|
|
124
124
|
autocomplete="off"
|
|
125
125
|
required
|
|
126
|
-
><md-icon slot="leading-icon">
|
|
126
|
+
><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
|
|
127
127
|
>
|
|
128
128
|
</div>
|
|
129
129
|
|
|
130
|
-
<md-elevated-button class="ui" type="
|
|
130
|
+
<md-elevated-button class="ui" type="button" raised @click=${e => this._onSubmit(e)}>
|
|
131
131
|
<ox-i18n msgid="field.${this.pageName}"> </ox-i18n>
|
|
132
132
|
</md-elevated-button>
|
|
133
133
|
`;
|
|
@@ -154,7 +154,7 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
|
|
|
154
154
|
${ssoLinks.map(sso => html `
|
|
155
155
|
<a class="link" href=${sso.link}>
|
|
156
156
|
<md-text-button>
|
|
157
|
-
<md-icon slot="icon">
|
|
157
|
+
<md-icon slot="icon">id_card</md-icon>
|
|
158
158
|
${i18next.t('label.signin with', { title: sso.title })}
|
|
159
159
|
</md-text-button>
|
|
160
160
|
</a>
|