@things-factory/auth-ui 8.0.0-beta.8 → 8.0.0
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/auth-style-sign.ts +194 -0
- package/client/bootstrap.ts +51 -0
- package/client/components/abstract-auth-page.ts +301 -0
- package/client/components/abstract-password-reset.ts +168 -0
- package/client/components/abstract-sign.ts +127 -0
- package/client/components/change-password.ts +153 -0
- package/client/components/contact-us.ts +113 -0
- package/client/components/create-domain-popup.ts +141 -0
- package/client/components/create-role.ts +123 -0
- package/client/components/create-user.ts +95 -0
- package/client/components/credential-manager.ts +64 -0
- package/client/components/delete-user-popup.ts +117 -0
- package/client/components/domain-switch.ts +127 -0
- package/client/components/invite-customer.ts +104 -0
- package/client/components/invite-user.ts +96 -0
- package/client/components/my-login-history.ts +101 -0
- package/client/components/ownership-transfer-popup.ts +110 -0
- package/client/components/partner-info-card.ts +89 -0
- package/client/components/partner-role-editor.ts +153 -0
- package/client/components/profile-component.ts +332 -0
- package/client/components/role-edit-form.ts +92 -0
- package/client/components/role-privilege-editor.ts +267 -0
- package/client/components/role-selector.ts +102 -0
- package/client/components/user-role-editor.ts +499 -0
- package/client/constants/application.ts +9 -0
- package/client/constants/index.ts +1 -0
- package/client/entries/auth/activate.ts +272 -0
- package/client/entries/auth/checkin.ts +190 -0
- package/client/entries/auth/forgot-password.ts +103 -0
- package/client/entries/auth/reset-password.ts +22 -0
- package/client/entries/auth/result.ts +193 -0
- package/client/entries/auth/signin.ts +18 -0
- package/client/entries/auth/signup.ts +109 -0
- package/client/entries/auth/unlock-user.ts +22 -0
- package/client/entries/oauth2/oauth2-decision-error-page.ts +50 -0
- package/client/entries/oauth2/oauth2-decision-page.ts +196 -0
- package/client/entries/public/home.ts +246 -0
- package/client/index.ts +124 -0
- package/client/pages/app-binding/app-binding.ts +423 -0
- package/client/pages/app-binding/app-bindings.ts +171 -0
- package/client/pages/appliance/appliance.ts +452 -0
- package/client/pages/appliance/home.ts +177 -0
- package/client/pages/appliance/register.ts +183 -0
- package/client/pages/application/application.ts +428 -0
- package/client/pages/application/applications.ts +182 -0
- package/client/pages/application/register.ts +211 -0
- package/client/pages/attribute/attribute-set-item-list.ts +237 -0
- package/client/pages/attribute/attribute-set-management.ts +282 -0
- package/client/pages/auth-provider/auth-provider-management.ts +381 -0
- package/client/pages/domain/domain-management.ts +410 -0
- package/client/pages/partner/partner-management.ts +112 -0
- package/client/pages/profile.ts +32 -0
- package/client/pages/role/role-management.ts +134 -0
- package/client/pages/user/user-management.ts +224 -0
- package/client/route.ts +67 -0
- package/client/themes/auth-theme.css +65 -0
- package/client/utils/password-rule.ts +37 -0
- 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.d.ts +2 -1
- package/dist-client/components/abstract-password-reset.js +14 -7
- package/dist-client/components/abstract-password-reset.js.map +1 -1
- package/dist-client/components/abstract-sign.js +11 -12
- 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 +7 -10
- package/dist-client/components/contact-us.js.map +1 -1
- package/dist-client/components/create-user.js +5 -28
- package/dist-client/components/create-user.js.map +1 -1
- package/dist-client/components/invite-user.js +11 -19
- package/dist-client/components/invite-user.js.map +1 -1
- package/dist-client/components/ownership-transfer-popup.js +3 -3
- package/dist-client/components/ownership-transfer-popup.js.map +1 -1
- package/dist-client/components/profile-component.d.ts +1 -5
- package/dist-client/components/profile-component.js +4 -64
- package/dist-client/components/profile-component.js.map +1 -1
- package/dist-client/components/role-privilege-editor.js +1 -2
- package/dist-client/components/role-privilege-editor.js.map +1 -1
- package/dist-client/components/user-role-editor.js +18 -18
- package/dist-client/components/user-role-editor.js.map +1 -1
- package/dist-client/entries/auth/checkin.js +1 -1
- package/dist-client/entries/auth/checkin.js.map +1 -1
- package/dist-client/entries/auth/forgot-password.js +2 -11
- package/dist-client/entries/auth/forgot-password.js.map +1 -1
- package/dist-client/entries/auth/signup.js +7 -13
- 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 +1 -5
- package/dist-client/pages/user/user-management.js +7 -6
- 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 +12 -12
- package/server/index.ts +0 -0
- package/translations/en.json +2 -6
- package/translations/ja.json +2 -6
- package/translations/ko.json +2 -6
- package/translations/ms.json +2 -6
- package/translations/zh.json +2 -6
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js'
|
|
2
|
+
|
|
3
|
+
import '@things-factory/component-ui'
|
|
4
|
+
import '../../components/invite-user'
|
|
5
|
+
import '../../components/ownership-transfer-popup'
|
|
6
|
+
import '../../components/user-role-editor'
|
|
7
|
+
import '../../components/create-user'
|
|
8
|
+
|
|
9
|
+
import gql from 'graphql-tag'
|
|
10
|
+
import { css, html } from 'lit'
|
|
11
|
+
import { customElement, property, query } from 'lit/decorators.js'
|
|
12
|
+
|
|
13
|
+
import { client, gqlContext } from '@operato/graphql'
|
|
14
|
+
import { i18next, localize } from '@operato/i18n'
|
|
15
|
+
import { PageView } from '@operato/shell'
|
|
16
|
+
import { OxPrompt } from '@operato/popup/ox-prompt.js'
|
|
17
|
+
|
|
18
|
+
@customElement('user-management')
|
|
19
|
+
export class UserManagement extends localize(i18next)(PageView) {
|
|
20
|
+
static styles = [
|
|
21
|
+
css`
|
|
22
|
+
:host {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
background-color: var(--md-sys-color-background);
|
|
26
|
+
padding: var(--spacing-large);
|
|
27
|
+
overflow: auto;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@media screen and (max-width: 600px) {
|
|
31
|
+
:host {
|
|
32
|
+
padding: var(--spacing-small);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
@property({ type: Array }) domainUsers: any[] = []
|
|
39
|
+
@property({ type: Object }) owner: any
|
|
40
|
+
@property({ type: String }) currentTab: string = ''
|
|
41
|
+
@property({ type: Boolean }) passwordResettable: boolean = false
|
|
42
|
+
@property({ type: Boolean }) userCreatable: boolean = false
|
|
43
|
+
|
|
44
|
+
@query('#user-list') userListElement!: HTMLElement & { close: () => void }
|
|
45
|
+
|
|
46
|
+
get context() {
|
|
47
|
+
return {
|
|
48
|
+
title: i18next.t('text.user management'),
|
|
49
|
+
help: 'auth/users'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render() {
|
|
54
|
+
const groupingUser = (this.domainUsers || []).reduce(
|
|
55
|
+
(groupingUser, user) => {
|
|
56
|
+
const userType = user.userType
|
|
57
|
+
if (!groupingUser[userType]) {
|
|
58
|
+
groupingUser[userType] = []
|
|
59
|
+
}
|
|
60
|
+
user.activated = user.status === 'activated'
|
|
61
|
+
groupingUser[userType].push(user)
|
|
62
|
+
|
|
63
|
+
return groupingUser
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
admin: [],
|
|
67
|
+
user: [],
|
|
68
|
+
application: [],
|
|
69
|
+
appliance: []
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
const USER_TYPES = {
|
|
74
|
+
USER: i18next.t('label.user'),
|
|
75
|
+
APPLICATION: i18next.t('label.application'),
|
|
76
|
+
APPLIANCE: i18next.t('text.appliance')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const userSet = {
|
|
80
|
+
[USER_TYPES.USER]: [...groupingUser.user, ...groupingUser.admin],
|
|
81
|
+
[USER_TYPES.APPLICATION]: groupingUser.application,
|
|
82
|
+
[USER_TYPES.APPLIANCE]: groupingUser.appliance
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return html`
|
|
86
|
+
${this.userCreatable
|
|
87
|
+
? html`<create-user
|
|
88
|
+
@create-user=${async event => {
|
|
89
|
+
const user = event.detail
|
|
90
|
+
user.userType = 'user'
|
|
91
|
+
|
|
92
|
+
await this.createUser(user)
|
|
93
|
+
}}
|
|
94
|
+
></create-user>`
|
|
95
|
+
: ''}
|
|
96
|
+
<quick-find-list
|
|
97
|
+
id="user-list"
|
|
98
|
+
.data=${userSet}
|
|
99
|
+
@tabChanged=${e => (this.currentTab = e.detail.currentTabKey)}
|
|
100
|
+
.headerRenderer=${user => {
|
|
101
|
+
return html`
|
|
102
|
+
${!user.activated
|
|
103
|
+
? html`
|
|
104
|
+
<md-icon>do_disturb</md-icon>
|
|
105
|
+
${user.name}
|
|
106
|
+
`
|
|
107
|
+
: html` ${user.owner ? html` <md-icon>supervisor_account</md-icon> ` : ''} ${user.name} `}
|
|
108
|
+
`
|
|
109
|
+
}}
|
|
110
|
+
.contentRenderer=${user =>
|
|
111
|
+
html` <user-role-editor
|
|
112
|
+
.user=${user}
|
|
113
|
+
.domainOwner=${this.owner}
|
|
114
|
+
.activate=${user.activated}
|
|
115
|
+
@userUpdated=${this.refreshUsers.bind(this)}
|
|
116
|
+
@ownershipTransferred=${this.refreshUsers.bind(this)}
|
|
117
|
+
.passwordResettable=${this.passwordResettable}
|
|
118
|
+
></user-role-editor>`}
|
|
119
|
+
></quick-find-list>
|
|
120
|
+
|
|
121
|
+
${this.currentTab === USER_TYPES.USER
|
|
122
|
+
? html`<invite-user @invitationCompleted=${this.refreshUsers.bind(this)}></invite-user>`
|
|
123
|
+
: ''}
|
|
124
|
+
`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async pageUpdated(changes, lifecycle, before) {
|
|
128
|
+
if (this.active) {
|
|
129
|
+
this.refreshUsers()
|
|
130
|
+
this.checkPasswordResettable()
|
|
131
|
+
this.checkUserCreatable()
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async refreshUsers() {
|
|
136
|
+
const domainUsersResp = await client.query({
|
|
137
|
+
query: gql`
|
|
138
|
+
query {
|
|
139
|
+
users {
|
|
140
|
+
items {
|
|
141
|
+
id
|
|
142
|
+
name
|
|
143
|
+
email
|
|
144
|
+
userType
|
|
145
|
+
status
|
|
146
|
+
owner
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
`,
|
|
151
|
+
context: gqlContext()
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
if (!domainUsersResp.errors?.length) {
|
|
155
|
+
this.domainUsers = domainUsersResp.data.users.items || []
|
|
156
|
+
this.owner = this.domainUsers.filter(user => user.owner)[0] || {}
|
|
157
|
+
this.userListElement?.close()
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async checkPasswordResettable() {
|
|
162
|
+
const response = await client.query({
|
|
163
|
+
query: gql`
|
|
164
|
+
query {
|
|
165
|
+
checkResettablePasswordToDefault
|
|
166
|
+
}
|
|
167
|
+
`
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
if (!response.errors) {
|
|
171
|
+
this.passwordResettable = response.data.checkResettablePasswordToDefault
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async checkUserCreatable() {
|
|
176
|
+
const response = await client.query({
|
|
177
|
+
query: gql`
|
|
178
|
+
query {
|
|
179
|
+
checkDefaultPassword
|
|
180
|
+
}
|
|
181
|
+
`
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
if (!response.errors) {
|
|
185
|
+
this.userCreatable = response.data.checkDefaultPassword
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async createUser(user) {
|
|
190
|
+
if (
|
|
191
|
+
await OxPrompt.open({
|
|
192
|
+
title: i18next.t('text.are_you_sure'),
|
|
193
|
+
text: i18next.t('text.are_you_sure_to_x_user', { x: i18next.t('button.create') }),
|
|
194
|
+
confirmButton: { text: i18next.t('button.confirm') },
|
|
195
|
+
cancelButton: { text: i18next.t('button.cancel') }
|
|
196
|
+
})
|
|
197
|
+
) {
|
|
198
|
+
const response = await client.mutate({
|
|
199
|
+
mutation: gql`
|
|
200
|
+
mutation createUser($user: NewUser!) {
|
|
201
|
+
createUser(user: $user) {
|
|
202
|
+
name
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
`,
|
|
206
|
+
variables: { user },
|
|
207
|
+
context: gqlContext()
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
if (!response.errors) {
|
|
211
|
+
await OxPrompt.open({
|
|
212
|
+
title: i18next.t('text.completed'),
|
|
213
|
+
confirmButton: { text: i18next.t('button.confirm') }
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
await this.refreshUsers()
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
showToast(message) {
|
|
222
|
+
document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
|
|
223
|
+
}
|
|
224
|
+
}
|
package/client/route.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export default function route(page) {
|
|
2
|
+
switch (page) {
|
|
3
|
+
case 'profile':
|
|
4
|
+
import(
|
|
5
|
+
/* webpackPrefetch: true */
|
|
6
|
+
/* webpackChunkName: "profile" */
|
|
7
|
+
'./pages/profile.js'
|
|
8
|
+
)
|
|
9
|
+
return page
|
|
10
|
+
|
|
11
|
+
case 'appliance-register':
|
|
12
|
+
import('./pages/appliance/register')
|
|
13
|
+
return page
|
|
14
|
+
|
|
15
|
+
case 'application':
|
|
16
|
+
import('./pages/application/application')
|
|
17
|
+
return page
|
|
18
|
+
|
|
19
|
+
case 'applications':
|
|
20
|
+
import('./pages/application/applications')
|
|
21
|
+
return page
|
|
22
|
+
|
|
23
|
+
case 'application-register':
|
|
24
|
+
import('./pages/application/register')
|
|
25
|
+
return page
|
|
26
|
+
|
|
27
|
+
case 'app-bindings':
|
|
28
|
+
import('./pages/app-binding/app-bindings')
|
|
29
|
+
return page
|
|
30
|
+
|
|
31
|
+
case 'app-binding':
|
|
32
|
+
import('./pages/app-binding/app-binding')
|
|
33
|
+
return page
|
|
34
|
+
|
|
35
|
+
case 'appliance-home':
|
|
36
|
+
import('./pages/appliance/home')
|
|
37
|
+
return page
|
|
38
|
+
|
|
39
|
+
case 'appliance':
|
|
40
|
+
import('./pages/appliance/appliance')
|
|
41
|
+
return page
|
|
42
|
+
|
|
43
|
+
case 'roles':
|
|
44
|
+
import('./pages/role/role-management')
|
|
45
|
+
return page
|
|
46
|
+
|
|
47
|
+
case 'users':
|
|
48
|
+
import('./pages/user/user-management')
|
|
49
|
+
return page
|
|
50
|
+
|
|
51
|
+
case 'partners':
|
|
52
|
+
import('./pages/partner/partner-management')
|
|
53
|
+
return page
|
|
54
|
+
|
|
55
|
+
case 'domains':
|
|
56
|
+
import('./pages/domain/domain-management')
|
|
57
|
+
return page
|
|
58
|
+
|
|
59
|
+
case 'attributes':
|
|
60
|
+
import('./pages/attribute/attribute-set-management.js')
|
|
61
|
+
return page
|
|
62
|
+
|
|
63
|
+
case 'auth-providers':
|
|
64
|
+
import('./pages/auth-provider/auth-provider-management.js')
|
|
65
|
+
return page
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
body {
|
|
2
|
+
/* login page style*/
|
|
3
|
+
--auth-brand-name: bold 20px var(--theme-font);
|
|
4
|
+
--auth-brand-name-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
|
|
5
|
+
--auth-brand-welcome-msg: normal 12px var(--theme-font);
|
|
6
|
+
|
|
7
|
+
--auth-title-font: bold 32px var(--theme-font);
|
|
8
|
+
--auth-description-font: normal 12px var(--theme-font);
|
|
9
|
+
--auth-description-padding: 5px 5px 15px 5px;
|
|
10
|
+
|
|
11
|
+
--auth-input-font: normal 18px/24px var(--theme-font);
|
|
12
|
+
--auth-input-border: 1px solid rgba(0, 0, 0, 0.4);
|
|
13
|
+
--auth-input-border-light: 1px solid rgba(255, 255, 255, 0.8);
|
|
14
|
+
--auth-input-color: var(--md-sys-color-on-primary);
|
|
15
|
+
|
|
16
|
+
--auth-button-background-color: var(--md-sys-color-surface-variant);
|
|
17
|
+
--auth-button-background-focus-color: var(--status-success-color);
|
|
18
|
+
--auth-button-font: bold 20px var(--theme-font);
|
|
19
|
+
--auth-button-padding: 9px 12px 7px 12px;
|
|
20
|
+
|
|
21
|
+
/* profile page style*/
|
|
22
|
+
--profile-brand-width: 150px;
|
|
23
|
+
--profile-brand-height: 45px;
|
|
24
|
+
--profile-brand-padding: 30px auto 20px auto;
|
|
25
|
+
|
|
26
|
+
--profile-wrap-max-width: 550px;
|
|
27
|
+
--profile-icon-margin: 7% 0 0 0;
|
|
28
|
+
|
|
29
|
+
--auth-input-field-width: 100%;
|
|
30
|
+
--auth-input-field-font: normal 16px var(--theme-font);
|
|
31
|
+
|
|
32
|
+
--change-password-field-font: var(--auth-input-field-font);
|
|
33
|
+
--change-password-field-border: 1px solid rgba(0, 0, 0, 0.2);
|
|
34
|
+
--change-password-field-border-radius: var(--border-radius);
|
|
35
|
+
--change-password-field-margin: var(--margin-narrow) 0;
|
|
36
|
+
--change-password-field-padding: var(--padding-default);
|
|
37
|
+
--change-password-field-width: var(--auth-input-field-width);
|
|
38
|
+
|
|
39
|
+
--auth-special-page-padding: 250px 0 100px 0;
|
|
40
|
+
|
|
41
|
+
/* domain select page style*/
|
|
42
|
+
--checkin-background-color: var(--md-sys-color-background);
|
|
43
|
+
--checkin-header-height: 45px;
|
|
44
|
+
--checkin-header-background-color: var(--md-sys-color-primary);
|
|
45
|
+
--checkin-header-title-font: bold 19px var(--theme-font);
|
|
46
|
+
--checkin-header-title-color: var(--md-sys-color-on-primary);
|
|
47
|
+
--checkin-wrap-max-width: 500px;
|
|
48
|
+
--checkin-wrap-padding: var(--padding-wide);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@media only screen and (max-width: 460px) {
|
|
52
|
+
body {
|
|
53
|
+
/* profile page style*/
|
|
54
|
+
--profile-wrap-max-width: 85vw;
|
|
55
|
+
|
|
56
|
+
--auth-input-field-font: normal 20px var(--theme-font);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (min-width: 461px) and (max-width: 1024px) {
|
|
61
|
+
body {
|
|
62
|
+
/* profile page style*/
|
|
63
|
+
--auth-input-field-font: normal 20px var(--theme-font);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { i18next } from '@operato/i18n'
|
|
2
|
+
|
|
3
|
+
export { generatePasswordPatternRegExp } from '@operato/utils'
|
|
4
|
+
|
|
5
|
+
export function generatePasswordPatternHelp({
|
|
6
|
+
lowerCase = true,
|
|
7
|
+
upperCase = true,
|
|
8
|
+
digit = true,
|
|
9
|
+
specialCharacter = true,
|
|
10
|
+
allowRepeat = false,
|
|
11
|
+
useTightPattern = true,
|
|
12
|
+
useLoosePattern = false,
|
|
13
|
+
tightCharacterLength = 8,
|
|
14
|
+
looseCharacterLength = 15
|
|
15
|
+
} = {}) {
|
|
16
|
+
var descriptions: string[] = []
|
|
17
|
+
|
|
18
|
+
if (useLoosePattern) {
|
|
19
|
+
descriptions.push(`more than ${looseCharacterLength} characters`)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (useTightPattern) {
|
|
23
|
+
!useLoosePattern &&
|
|
24
|
+
descriptions.push(
|
|
25
|
+
i18next.t('text.pattern_minimum_charaters', {
|
|
26
|
+
length: tightCharacterLength
|
|
27
|
+
})
|
|
28
|
+
)
|
|
29
|
+
lowerCase && descriptions.push(i18next.t('text.pattern_atleast_1_lowercase'))
|
|
30
|
+
upperCase && descriptions.push(i18next.t('text.pattern_atleast_1_uppercase'))
|
|
31
|
+
digit && descriptions.push(i18next.t('text.pattern_atleast_1_digit'))
|
|
32
|
+
specialCharacter && descriptions.push(i18next.t('text.pattern_atleast_1_special'))
|
|
33
|
+
!allowRepeat && descriptions.push(i18next.t('text.pattern_not_allowed'))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return descriptions.join(', ')
|
|
37
|
+
}
|
|
@@ -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 email = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.email) || '';
|
|
103
|
+
// .validationMessage=${String(i18next.t('text.invalid-email'))}
|
|
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.
|
|
109
|
+
name="email"
|
|
110
|
+
type="email"
|
|
111
|
+
label=${String(i18next.t('field.email'))}
|
|
112
112
|
required
|
|
113
|
-
.value=${
|
|
113
|
+
.value=${email}
|
|
114
114
|
autocomplete="off"
|
|
115
115
|
autocapitalize="off"
|
|
116
|
-
><md-icon slot="leading-icon">
|
|
116
|
+
><md-icon slot="leading-icon">mail</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">vpn_key</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="submit" 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">badge</md-icon>
|
|
158
158
|
${i18next.t('label.signin with', { title: sso.title })}
|
|
159
159
|
</md-text-button>
|
|
160
160
|
</a>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-auth-page.js","sourceRoot":"","sources":["../../client/components/abstract-auth-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/textfield/filled-text-field.js'\n\nimport '@operato/lottie-player'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport '@operato/layout/ox-snack-bar.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { isSafari } from '@operato/utils'\n\nimport { AUTH_STYLE_SIGN } from '../auth-style-sign.js'\n\nexport abstract class AbstractAuthPage extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n position: relative;\n overflow: hidden;\n\n display: flex;\n flex-direction: row;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n }\n\n .content {\n flex: 1;\n overflow: auto;\n }\n\n .home {\n position: absolute;\n padding: var(--padding-dufault, 9px);\n left: 20px;\n top: 10px;\n color: var(--md-sys-color-on-primary);\n }\n\n div.field {\n margin-bottom: var(--spacing-medium);\n }\n\n [hidden] {\n display: none;\n }\n\n #snackbar {\n width: 100%;\n z-index: 10;\n }\n\n @media print {\n :host {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n min-height: 100dvh;\n }\n }\n `,\n AUTH_STYLE_SIGN\n ]\n\n @property({ type: Object }) data: any\n @property({ type: String }) message?: string\n @property({ type: Object }) detail: any\n @property({ type: String }) redirectTo?: string\n\n @query('#form') formEl!: HTMLFormElement\n\n private _applicationMeta?: {\n icon: string\n title: string\n description: string\n }\n\n get autocompletable() {\n return false\n }\n\n render() {\n const { disableUserFavoredLanguage, languages } = this.data || {}\n var { icon, title, description } = this.applicationMeta\n\n return html`\n <div class=\"content md-typescale-display-medium\">\n <div class=\"wrap\">\n <div class=\"auth-brand\">\n <img src=${icon} />\n <strong class=\"name\">${title}</strong>\n <span class=\"welcome-msg\">${description}</span>\n </div>\n\n <div class=\"auth-form\">\n <h3><ox-i18n msgid=\"title.${this.pageName}\"></ox-i18n></h3>\n\n <form\n id=\"form\"\n action=\"${this.actionUrl}\"\n method=\"post\"\n autocomplete=${this.autocompletable ? 'on' : 'off'}\n @keypress=${e => {\n if (e.key == 'Enter') this._onSubmit(e)\n }}\n >\n ${this.formfields}\n </form>\n ${this.links}\n ${!disableUserFavoredLanguage\n ? html` <div id=\"locale-area\">\n <label for=\"locale-selector\"><md-icon>language</md-icon></label>\n <ox-i18n-selector\n id=\"locale-selector\"\n value=${i18next.language || 'en-US'}\n .languages=${languages}\n @change=${e => {\n var locale = e.detail\n if (!locale) return\n\n i18next.changeLanguage(locale)\n }}\n ></ox-i18n-selector>\n </div>`\n : nothing}\n </div>\n </div>\n\n <md-icon-button class=\"home\" @click=${e => (window.location.href = '/')}\n ><md-icon>home</md-icon></md-icon-button\n >\n <ox-snack-bar id=\"snackbar\" level=\"error\" .message=${this.message}></ox-snack-bar>\n\n ${isSafari()\n ? html``\n : html`\n <div class=\"lottie-container\">\n <lottie-player autoplay loop src=\"../../assets/images/background-animation.json\"></lottie-player>\n </div>\n `}\n </div>\n `\n }\n\n firstUpdated() {\n setTimeout(() => {\n ;(this.renderRoot.querySelector('md-filled-text-field') as any).focus()\n }, 100)\n\n this.formEl.reset = () => {\n this.formElements.filter(el => !(el.hidden || el.type == 'hidden')).forEach(el => (el.value = ''))\n }\n }\n\n updated(changed) {\n if (changed.has('data') && this.data) {\n this.message = this.data.message\n this.redirectTo = this.data.redirectTo\n }\n }\n\n abstract get pageName(): string\n abstract get actionUrl(): string\n\n get formElements(): HTMLInputElement[] {\n return Array.from(this.formEl.querySelectorAll('[name]'))\n }\n\n get formfields() {\n const username = this.data?.username || ''\n // .validationMessage=${String(i18next.t('text.invalid-username'))}\n\n return html`\n <input id=\"redirectTo\" type=\"hidden\" name=\"redirectTo\" .value=${this.redirectTo || '/'} />\n\n <div class=\"field\">\n <md-filled-text-field\n name=\"username\"\n type=\"text\"\n label=${String(i18next.t('field.user-id or email'))}\n required\n .value=${username}\n autocomplete=\"off\"\n autocapitalize=\"off\"\n ><md-icon slot=\"leading-icon\">id_card</md-icon></md-filled-text-field\n >\n </div>\n <div class=\"field\">\n <md-filled-text-field\n name=\"password\"\n type=\"password\"\n label=${String(i18next.t('field.password'))}\n autocomplete=\"off\"\n required\n ><md-icon slot=\"leading-icon\">password</md-icon></md-filled-text-field\n >\n </div>\n\n <md-elevated-button class=\"ui\" type=\"button\" raised @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"field.${this.pageName}\"> </ox-i18n>\n </md-elevated-button>\n `\n }\n\n get links() {\n const { disableUserSignupProcess, ssoLinks = [] } = this.data || {}\n\n return html`\n ${!disableUserSignupProcess\n ? html`\n <a class=\"link\" href=\"/auth/signup\">\n <md-text-button>\n <md-icon slot=\"icon\">add_task</md-icon>\n <ox-i18n msgid=\"field.sign up\"></ox-i18n>\n </md-text-button>\n </a>\n <a class=\"link\" href=\"/auth/forgot-password\">\n <md-text-button>\n <md-icon slot=\"icon\">lock_open</md-icon>\n <ox-i18n msgid=\"field.forgot-password\"></ox-i18n>\n </md-text-button>\n </a>\n `\n : nothing}\n ${ssoLinks.map(\n sso => html`\n <a class=\"link\" href=${sso.link}>\n <md-text-button>\n <md-icon slot=\"icon\">id_card</md-icon>\n ${i18next.t('label.signin with', { title: sso.title })}\n </md-text-button>\n </a>\n `\n )}\n `\n }\n\n async _onSubmit(e) {\n if (this.checkValidity()) {\n this.submit()\n }\n }\n\n checkValidity() {\n return this.formElements.every(el => el.checkValidity())\n }\n\n abstract submit()\n\n showSnackbar({ level, message, timer = 3000 }: { level?: string; message?: string; timer?: number } = {}) {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n if (level) snackbar.level = level\n if (message) snackbar.message = message\n snackbar.active = true\n\n if (timer > -1)\n setTimeout(() => {\n this.hideSnackbar()\n }, timer)\n }\n\n hideSnackbar() {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n snackbar.active = false\n }\n\n get applicationMeta() {\n if (!this._applicationMeta) {\n var iconLink: HTMLLinkElement | null = document.querySelector('link[rel=\"application-icon\"]')\n var titleMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-name\"]')\n var descriptionMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-description\"]')\n\n this._applicationMeta = {\n icon: iconLink?.href || '',\n title: titleMeta?.content || 'Things Factory',\n description: descriptionMeta?.content || 'Reimagining Software'\n }\n }\n\n return this._applicationMeta\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"abstract-auth-page.js","sourceRoot":"","sources":["../../client/components/abstract-auth-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/textfield/filled-text-field.js'\n\nimport '@operato/lottie-player'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport '@operato/layout/ox-snack-bar.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { isSafari } from '@operato/utils'\n\nimport { AUTH_STYLE_SIGN } from '../auth-style-sign.js'\n\nexport abstract class AbstractAuthPage extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n position: relative;\n overflow: hidden;\n\n display: flex;\n flex-direction: row;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n }\n\n .content {\n flex: 1;\n overflow: auto;\n }\n\n .home {\n position: absolute;\n padding: var(--padding-dufault, 9px);\n left: 20px;\n top: 10px;\n color: var(--md-sys-color-on-primary);\n }\n\n div.field {\n margin-bottom: var(--spacing-medium);\n }\n\n [hidden] {\n display: none;\n }\n\n #snackbar {\n width: 100%;\n z-index: 10;\n }\n\n @media print {\n :host {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n min-height: 100dvh;\n }\n }\n `,\n AUTH_STYLE_SIGN\n ]\n\n @property({ type: Object }) data: any\n @property({ type: String }) message?: string\n @property({ type: Object }) detail: any\n @property({ type: String }) redirectTo?: string\n\n @query('#form') formEl!: HTMLFormElement\n\n private _applicationMeta?: {\n icon: string\n title: string\n description: string\n }\n\n get autocompletable() {\n return false\n }\n\n render() {\n const { disableUserFavoredLanguage, languages } = this.data || {}\n var { icon, title, description } = this.applicationMeta\n\n return html`\n <div class=\"content md-typescale-display-medium\">\n <div class=\"wrap\">\n <div class=\"auth-brand\">\n <img src=${icon} />\n <strong class=\"name\">${title}</strong>\n <span class=\"welcome-msg\">${description}</span>\n </div>\n\n <div class=\"auth-form\">\n <h3><ox-i18n msgid=\"title.${this.pageName}\"></ox-i18n></h3>\n\n <form\n id=\"form\"\n action=\"${this.actionUrl}\"\n method=\"post\"\n autocomplete=${this.autocompletable ? 'on' : 'off'}\n @keypress=${e => {\n if (e.key == 'Enter') this._onSubmit(e)\n }}\n >\n ${this.formfields}\n </form>\n ${this.links}\n ${!disableUserFavoredLanguage\n ? html` <div id=\"locale-area\">\n <label for=\"locale-selector\"><md-icon>language</md-icon></label>\n <ox-i18n-selector\n id=\"locale-selector\"\n value=${i18next.language || 'en-US'}\n .languages=${languages}\n @change=${e => {\n var locale = e.detail\n if (!locale) return\n\n i18next.changeLanguage(locale)\n }}\n ></ox-i18n-selector>\n </div>`\n : nothing}\n </div>\n </div>\n\n <md-icon-button class=\"home\" @click=${e => (window.location.href = '/')}\n ><md-icon>home</md-icon></md-icon-button\n >\n <ox-snack-bar id=\"snackbar\" level=\"error\" .message=${this.message}></ox-snack-bar>\n\n ${isSafari()\n ? html``\n : html`\n <div class=\"lottie-container\">\n <lottie-player autoplay loop src=\"../../assets/images/background-animation.json\"></lottie-player>\n </div>\n `}\n </div>\n `\n }\n\n firstUpdated() {\n setTimeout(() => {\n ;(this.renderRoot.querySelector('md-filled-text-field') as any).focus()\n }, 100)\n\n this.formEl.reset = () => {\n this.formElements.filter(el => !(el.hidden || el.type == 'hidden')).forEach(el => (el.value = ''))\n }\n }\n\n updated(changed) {\n if (changed.has('data') && this.data) {\n this.message = this.data.message\n this.redirectTo = this.data.redirectTo\n }\n }\n\n abstract get pageName(): string\n abstract get actionUrl(): string\n\n get formElements(): HTMLInputElement[] {\n return Array.from(this.formEl.querySelectorAll('[name]'))\n }\n\n get formfields() {\n const email = this.data?.email || ''\n // .validationMessage=${String(i18next.t('text.invalid-email'))}\n\n return html`\n <input id=\"redirectTo\" type=\"hidden\" name=\"redirectTo\" .value=${this.redirectTo || '/'} />\n\n <div class=\"field\">\n <md-filled-text-field\n name=\"email\"\n type=\"email\"\n label=${String(i18next.t('field.email'))}\n required\n .value=${email}\n autocomplete=\"off\"\n autocapitalize=\"off\"\n ><md-icon slot=\"leading-icon\">mail</md-icon></md-filled-text-field\n >\n </div>\n <div class=\"field\">\n <md-filled-text-field\n name=\"password\"\n type=\"password\"\n label=${String(i18next.t('field.password'))}\n autocomplete=\"off\"\n required\n ><md-icon slot=\"leading-icon\">vpn_key</md-icon></md-filled-text-field\n >\n </div>\n\n <md-elevated-button class=\"ui\" type=\"submit\" raised @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"field.${this.pageName}\"> </ox-i18n>\n </md-elevated-button>\n `\n }\n\n get links() {\n const { disableUserSignupProcess, ssoLinks = [] } = this.data || {}\n\n return html`\n ${!disableUserSignupProcess\n ? html`\n <a class=\"link\" href=\"/auth/signup\">\n <md-text-button>\n <md-icon slot=\"icon\">add_task</md-icon>\n <ox-i18n msgid=\"field.sign up\"></ox-i18n>\n </md-text-button>\n </a>\n <a class=\"link\" href=\"/auth/forgot-password\">\n <md-text-button>\n <md-icon slot=\"icon\">lock_open</md-icon>\n <ox-i18n msgid=\"field.forgot-password\"></ox-i18n>\n </md-text-button>\n </a>\n `\n : nothing}\n ${ssoLinks.map(\n sso => html`\n <a class=\"link\" href=${sso.link}>\n <md-text-button>\n <md-icon slot=\"icon\">badge</md-icon>\n ${i18next.t('label.signin with', { title: sso.title })}\n </md-text-button>\n </a>\n `\n )}\n `\n }\n\n async _onSubmit(e) {\n if (this.checkValidity()) {\n this.submit()\n }\n }\n\n checkValidity() {\n return this.formElements.every(el => el.checkValidity())\n }\n\n abstract submit()\n\n showSnackbar({ level, message, timer = 3000 }: { level?: string; message?: string; timer?: number } = {}) {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n if (level) snackbar.level = level\n if (message) snackbar.message = message\n snackbar.active = true\n\n if (timer > -1)\n setTimeout(() => {\n this.hideSnackbar()\n }, timer)\n }\n\n hideSnackbar() {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n snackbar.active = false\n }\n\n get applicationMeta() {\n if (!this._applicationMeta) {\n var iconLink: HTMLLinkElement | null = document.querySelector('link[rel=\"application-icon\"]')\n var titleMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-name\"]')\n var descriptionMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-description\"]')\n\n this._applicationMeta = {\n icon: iconLink?.href || '',\n title: titleMeta?.content || 'Things Factory',\n description: descriptionMeta?.content || 'Reimagining Software'\n }\n }\n\n return this._applicationMeta\n }\n}\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import '@material/web/icon/icon.js';
|
|
2
2
|
import '@material/web/button/elevated-button.js';
|
|
3
3
|
import '@material/web/textfield/filled-text-field.js';
|
|
4
|
+
import '@operato/lottie-player';
|
|
5
|
+
import '../components/profile-component';
|
|
4
6
|
import '@operato/i18n/ox-i18n.js';
|
|
5
7
|
import '@operato/i18n/ox-i18n-selector.js';
|
|
6
8
|
import '@operato/layout/ox-snack-bar.js';
|
|
7
|
-
import '../components/profile-component';
|
|
8
9
|
import { AbstractAuthPage } from './abstract-auth-page';
|
|
9
10
|
export declare abstract class AbstractPasswordReset extends AbstractAuthPage {
|
|
10
11
|
static styles: import("lit").CSSResult[];
|
|
@@ -2,13 +2,15 @@ import { __decorate, __metadata } from "tslib";
|
|
|
2
2
|
import '@material/web/icon/icon.js';
|
|
3
3
|
import '@material/web/button/elevated-button.js';
|
|
4
4
|
import '@material/web/textfield/filled-text-field.js';
|
|
5
|
+
import '@operato/lottie-player';
|
|
6
|
+
import '../components/profile-component';
|
|
5
7
|
import '@operato/i18n/ox-i18n.js';
|
|
6
8
|
import '@operato/i18n/ox-i18n-selector.js';
|
|
7
9
|
import '@operato/layout/ox-snack-bar.js';
|
|
8
|
-
import '../components/profile-component';
|
|
9
10
|
import { css, html, nothing } from 'lit';
|
|
10
11
|
import { property, query } from 'lit/decorators.js';
|
|
11
12
|
import { i18next } from '@operato/i18n';
|
|
13
|
+
import { isSafari } from '@operato/utils';
|
|
12
14
|
import { AUTH_STYLE_SIGN } from '../auth-style-sign';
|
|
13
15
|
import { generatePasswordPatternHelp, generatePasswordPatternRegExp } from '../utils/password-rule';
|
|
14
16
|
import { AbstractAuthPage } from './abstract-auth-page';
|
|
@@ -54,8 +56,7 @@ export class AbstractPasswordReset extends AbstractAuthPage {
|
|
|
54
56
|
this.confirmPass.setAttribute('pattern', val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '[$&]'));
|
|
55
57
|
}}
|
|
56
58
|
required
|
|
57
|
-
|
|
58
|
-
>
|
|
59
|
+
></md-filled-text-field>
|
|
59
60
|
</div>
|
|
60
61
|
|
|
61
62
|
<div class="field">
|
|
@@ -66,11 +67,10 @@ export class AbstractPasswordReset extends AbstractAuthPage {
|
|
|
66
67
|
label=${String(i18next.t('field.confirm password'))}
|
|
67
68
|
autocomplete="off"
|
|
68
69
|
required
|
|
69
|
-
|
|
70
|
-
>
|
|
70
|
+
></md-filled-text-field>
|
|
71
71
|
</div>
|
|
72
72
|
|
|
73
|
-
<md-elevated-button id="submit-button" type="
|
|
73
|
+
<md-elevated-button id="submit-button" type="submit" @click=${e => this._onSubmit(e)}>
|
|
74
74
|
<ox-i18n msgid="${this.submitButtonLabel}"></ox-i18n>
|
|
75
75
|
</md-elevated-button>
|
|
76
76
|
|
|
@@ -93,8 +93,15 @@ export class AbstractPasswordReset extends AbstractAuthPage {
|
|
|
93
93
|
</form>
|
|
94
94
|
</div>
|
|
95
95
|
</div>
|
|
96
|
-
|
|
97
96
|
<ox-snack-bar id="snackbar" level="error" .message=${this.message}></ox-snack-bar>
|
|
97
|
+
|
|
98
|
+
${isSafari()
|
|
99
|
+
? html ``
|
|
100
|
+
: html `
|
|
101
|
+
<div class="lottie-container">
|
|
102
|
+
<lottie-player autoplay loop src="../../assets/images/background-animation.json"></lottie-player>
|
|
103
|
+
</div>
|
|
104
|
+
`}
|
|
98
105
|
`;
|
|
99
106
|
}
|
|
100
107
|
updated(changed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-password-reset.js","sourceRoot":"","sources":["../../client/components/abstract-password-reset.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,yCAAyC,CAAA;AAChD,OAAO,8CAA8C,CAAA;AAErD,OAAO,
|
|
1
|
+
{"version":3,"file":"abstract-password-reset.js","sourceRoot":"","sources":["../../client/components/abstract-password-reset.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@material/web/textfield/filled-text-field.js'\n\nimport '@operato/lottie-player'\nimport '../components/profile-component'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport '@operato/layout/ox-snack-bar.js'\n\nimport { css, html, nothing } from 'lit'\nimport { property, query } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\nimport { isSafari } from '@operato/utils'\n\nimport { AUTH_STYLE_SIGN } from '../auth-style-sign'\nimport { generatePasswordPatternHelp, generatePasswordPatternRegExp } from '../utils/password-rule'\nimport { AbstractAuthPage } from './abstract-auth-page'\n\nexport abstract class AbstractPasswordReset extends AbstractAuthPage {\n static styles = [\n css`\n :host {\n position: relative;\n overflow: hidden;\n\n display: flex;\n flex-direction: row;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n }\n\n @media print {\n :host {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n min-height: 100dvh;\n }\n }\n `,\n AUTH_STYLE_SIGN\n ]\n\n @property({ type: Object }) data: any\n @property({ type: String }) token?: string\n\n @query('#confirm-password') confirmPass!: HTMLElement\n\n private passwordPattern: string = ''\n private passwordHelp: string = ''\n\n abstract get submitButtonLabel(): string\n\n render() {\n var { icon, title, description } = this.applicationMeta\n const { disableUserFavoredLanguage, languages } = this.data || {}\n\n return html`\n <div class=\"wrap\">\n <div class=\"auth-brand\">\n <img src=${icon} />\n <strong class=\"name\">${title}</strong>\n <span class=\"welcome-msg\">${description}</span>\n </div>\n\n <div class=\"auth-form\">\n <h3><ox-i18n msgid=\"title.${this.title}\"></ox-i18n></h3>\n <form\n id=\"form\"\n action=\"${this.actionUrl}\"\n method=\"post\"\n @keypress=${e => {\n if (e.key == 'Enter') this._onSubmit(e)\n }}\n >\n <input name=\"token\" type=\"hidden\" .value=${this.token || ''} required />\n <div class=\"field\">\n <md-filled-text-field\n name=\"password\"\n type=\"password\"\n label=${String(i18next.t('label.password'))}\n pattern=${this.passwordPattern || ''}\n supporting-text=${this.passwordHelp}\n autocomplete=\"off\"\n @input=${e => {\n var val = e.target.value\n this.confirmPass.setAttribute('pattern', val.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '[$&]'))\n }}\n required\n ></md-filled-text-field>\n </div>\n\n <div class=\"field\">\n <md-filled-text-field\n id=\"confirm-password\"\n name=\"confirm-password\"\n type=\"password\"\n label=${String(i18next.t('field.confirm password'))}\n autocomplete=\"off\"\n required\n ></md-filled-text-field>\n </div>\n\n <md-elevated-button id=\"submit-button\" type=\"submit\" @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"${this.submitButtonLabel}\"></ox-i18n>\n </md-elevated-button>\n\n ${!disableUserFavoredLanguage\n ? html` <div id=\"locale-area\">\n <label for=\"locale-selector\"><md-icon>language</md-icon></label>\n <ox-i18n-selector\n id=\"locale-selector\"\n value=${i18next.language || 'en-US'}\n .languages=${languages}\n @change=${e => {\n var locale = e.detail\n if (!locale) return\n\n i18next.changeLanguage(locale)\n }}\n ></ox-i18n-selector>\n </div>`\n : nothing}\n </form>\n </div>\n </div>\n <ox-snack-bar id=\"snackbar\" level=\"error\" .message=${this.message}></ox-snack-bar>\n\n ${isSafari()\n ? html``\n : html`\n <div class=\"lottie-container\">\n <lottie-player autoplay loop src=\"../../assets/images/background-animation.json\"></lottie-player>\n </div>\n `}\n `\n }\n\n updated(changed) {\n super.updated(changed)\n if (changed.has('data')) {\n this.token = this.data.token\n }\n\n if (changed.has('message')) {\n if (!this.message) {\n this.hideSnackbar()\n } else {\n this.showSnackbar({\n timer: -1\n })\n }\n }\n }\n\n languageUpdated() {\n this.passwordPattern = generatePasswordPatternRegExp(this.data.passwordRule).source\n this.passwordHelp = generatePasswordPatternHelp(this.data.passwordRule)\n }\n\n async submit() {\n this.formEl.submit()\n }\n}\n"]}
|