@things-factory/auth-ui 8.0.2 → 8.0.8

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.
Files changed (63) hide show
  1. package/client/bootstrap.ts +7 -3
  2. package/client/components/abstract-auth-page.ts +10 -10
  3. package/client/components/abstract-password-reset.ts +8 -13
  4. package/client/components/abstract-sign.ts +13 -13
  5. package/client/components/contact-us.ts +11 -8
  6. package/client/components/create-user.ts +27 -5
  7. package/client/components/invite-user.ts +18 -10
  8. package/client/components/ownership-transfer-popup.ts +3 -3
  9. package/client/components/profile-component.ts +64 -4
  10. package/client/components/user-role-editor.ts +18 -18
  11. package/client/entries/auth/checkin.ts +2 -9
  12. package/client/entries/auth/forgot-password.ts +2 -1
  13. package/client/entries/auth/signup.ts +13 -7
  14. package/client/index.ts +1 -1
  15. package/client/pages/domain/domain-management.ts +22 -2
  16. package/client/pages/user/user-management.ts +8 -9
  17. package/dist-client/bootstrap.d.ts +1 -1
  18. package/dist-client/bootstrap.js +2 -2
  19. package/dist-client/bootstrap.js.map +1 -1
  20. package/dist-client/components/abstract-auth-page.js +10 -10
  21. package/dist-client/components/abstract-auth-page.js.map +1 -1
  22. package/dist-client/components/abstract-password-reset.d.ts +1 -2
  23. package/dist-client/components/abstract-password-reset.js +6 -13
  24. package/dist-client/components/abstract-password-reset.js.map +1 -1
  25. package/dist-client/components/abstract-sign.js +12 -11
  26. package/dist-client/components/abstract-sign.js.map +1 -1
  27. package/dist-client/components/contact-us.d.ts +1 -1
  28. package/dist-client/components/contact-us.js +10 -7
  29. package/dist-client/components/contact-us.js.map +1 -1
  30. package/dist-client/components/create-user.js +28 -5
  31. package/dist-client/components/create-user.js.map +1 -1
  32. package/dist-client/components/invite-user.js +19 -11
  33. package/dist-client/components/invite-user.js.map +1 -1
  34. package/dist-client/components/ownership-transfer-popup.js +3 -3
  35. package/dist-client/components/ownership-transfer-popup.js.map +1 -1
  36. package/dist-client/components/profile-component.d.ts +5 -1
  37. package/dist-client/components/profile-component.js +64 -4
  38. package/dist-client/components/profile-component.js.map +1 -1
  39. package/dist-client/components/user-role-editor.js +18 -18
  40. package/dist-client/components/user-role-editor.js.map +1 -1
  41. package/dist-client/entries/auth/checkin.d.ts +1 -1
  42. package/dist-client/entries/auth/checkin.js +5 -12
  43. package/dist-client/entries/auth/checkin.js.map +1 -1
  44. package/dist-client/entries/auth/forgot-password.js +2 -1
  45. package/dist-client/entries/auth/forgot-password.js.map +1 -1
  46. package/dist-client/entries/auth/signup.js +13 -7
  47. package/dist-client/entries/auth/signup.js.map +1 -1
  48. package/dist-client/index.js +1 -1
  49. package/dist-client/index.js.map +1 -1
  50. package/dist-client/pages/domain/domain-management.d.ts +2 -0
  51. package/dist-client/pages/domain/domain-management.js +18 -2
  52. package/dist-client/pages/domain/domain-management.js.map +1 -1
  53. package/dist-client/pages/user/user-management.d.ts +5 -1
  54. package/dist-client/pages/user/user-management.js +6 -7
  55. package/dist-client/pages/user/user-management.js.map +1 -1
  56. package/dist-client/tsconfig.tsbuildinfo +1 -1
  57. package/dist-server/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +4 -4
  59. package/translations/en.json +4 -3
  60. package/translations/ja.json +4 -3
  61. package/translations/ko.json +4 -3
  62. package/translations/ms.json +4 -3
  63. package/translations/zh.json +4 -3
@@ -93,7 +93,7 @@ export class AuthCheckIn extends localize(i18next)(LitElement) {
93
93
 
94
94
  @property({ type: Object }) data: any
95
95
  @property({ type: Array }) domains: any[] = []
96
- @property({ type: String }) domainType?: string
96
+ @property({ type: Array }) domainTypes?: string[]
97
97
  @property({ type: Object }) user: any
98
98
 
99
99
  private _applicationMeta?: { icon?: string; title?: string; description?: string }
@@ -136,13 +136,6 @@ export class AuthCheckIn extends localize(i18next)(LitElement) {
136
136
  <md-elevated-button @click=${() => (location.pathname = '/auth/signout')}
137
137
  >${String(i18next.t('button.logout'))}</md-elevated-button
138
138
  >
139
-
140
- ${this.domainType?.toLowerCase() === 'company'
141
- ? html`<md-elevated-button
142
- @click=${e => (location.href = `/public/business-register?email=${this.user?.email}`)}
143
- >${String(i18next.t('button.register business domain'))}</md-elevated-button
144
- > `
145
- : ''}
146
139
  </div>
147
140
 
148
141
  ${isSafari()
@@ -161,7 +154,7 @@ export class AuthCheckIn extends localize(i18next)(LitElement) {
161
154
  if (changed.has('data')) {
162
155
  this.domains = this.data.domains
163
156
  this.user = this.data.user
164
- this.domainType = this.data.domainType
157
+ this.domainTypes = this.data.domainTypes
165
158
  this.redirectTo = this.data.redirectTo
166
159
 
167
160
  this.requestUpdate()
@@ -43,7 +43,8 @@ export class ForgotPassword extends AbstractAuthPage {
43
43
  target.setCustomValidity('')
44
44
  }
45
45
  }}
46
- ></md-filled-text-field>
46
+ ><md-icon slot="leading-icon">mail</md-icon></md-filled-text-field
47
+ >
47
48
  </div>
48
49
  <md-elevated-button id="submit-button" class="ui button" type="submit" @click=${e => this._onSubmit(e)}>
49
50
  <ox-i18n msgid="button.submit"></ox-i18n>
@@ -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="name"
35
+ name="username"
36
36
  type="text"
37
- label=${String(i18next.t('field.name'))}
38
- .value=${name}
37
+ label=${String(i18next.t('field.username'))}
38
+ .value=${username}
39
39
  required
40
- ></md-filled-text-field>
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>badge</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')
@@ -63,6 +63,8 @@ export class DomainManagement extends connect(store)(p13n(localize(i18next)(Page
63
63
  @property({ type: Object }) config: any
64
64
  @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'
65
65
 
66
+ private domainTypes?: string[]
67
+
66
68
  @query('ox-grist') private grist!: DataGrist
67
69
 
68
70
  get context() {
@@ -239,9 +241,11 @@ export class DomainManagement extends connect(store)(p13n(localize(i18next)(Page
239
241
  header: i18next.t('field.type'),
240
242
  record: {
241
243
  editable: true,
242
- options: []
244
+ options: async () => {
245
+ return ['', ...(await this.getDomainTypes())]
246
+ }
243
247
  },
244
- width: 70
248
+ width: 100
245
249
  },
246
250
  {
247
251
  type: 'select',
@@ -404,6 +408,22 @@ export class DomainManagement extends connect(store)(p13n(localize(i18next)(Page
404
408
  return response.data?.attributeSet || {}
405
409
  }
406
410
 
411
+ async getDomainTypes() {
412
+ if (!this.domainTypes) {
413
+ const response = await client.query({
414
+ query: gql`
415
+ query {
416
+ domainTypes
417
+ }
418
+ `
419
+ })
420
+
421
+ this.domainTypes = response.data?.domainTypes || ['domain']
422
+ }
423
+
424
+ return this.domainTypes || []
425
+ }
426
+
407
427
  showToast(message) {
408
428
  document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))
409
429
  }
@@ -98,14 +98,12 @@ export class UserManagement extends localize(i18next)(PageView) {
98
98
  .data=${userSet}
99
99
  @tabChanged=${e => (this.currentTab = e.detail.currentTabKey)}
100
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
- `
101
+ return !user.activated
102
+ ? html`
103
+ <md-icon>do_disturb</md-icon>
104
+ ${user.name}
105
+ `
106
+ : html` ${user.owner ? html` <md-icon>supervisor_account</md-icon> ` : ''} ${user.name} `
109
107
  }}
110
108
  .contentRenderer=${user =>
111
109
  html` <user-role-editor
@@ -139,6 +137,7 @@ export class UserManagement extends localize(i18next)(PageView) {
139
137
  users {
140
138
  items {
141
139
  id
140
+ username
142
141
  name
143
142
  email
144
143
  userType
@@ -186,7 +185,7 @@ export class UserManagement extends localize(i18next)(PageView) {
186
185
  }
187
186
  }
188
187
 
189
- async createUser(user) {
188
+ async createUser(user: { username: string; name: string; email: string }) {
190
189
  if (
191
190
  await OxPrompt.open({
192
191
  title: i18next.t('text.are_you_sure'),
@@ -1,4 +1,4 @@
1
1
  import '@material/web/icon/icon.js';
2
2
  import '@operato/i18n/ox-i18n.js';
3
3
  import '@operato/attribute/grist-editor';
4
- export default function bootstrap(): void;
4
+ export default function bootstrap(): Promise<void>;
@@ -8,7 +8,7 @@ import { OxGristEditorPrivilege } from '@operato/app/grist-editor/ox-grist-edito
8
8
  import { registerEditor as registerGristEditor, registerRenderer as registerGristRenderer, OxGristRendererJson5 } from '@operato/data-grist';
9
9
  import { auth } from '@things-factory/auth-base/dist-client/auth.js';
10
10
  import { ADD_MORENDA } from '@things-factory/more-base/client';
11
- export default function bootstrap() {
11
+ export default async function bootstrap() {
12
12
  registerGristEditor('privilege', OxGristEditorPrivilege);
13
13
  registerGristRenderer('privilege', OxGristRendererJson5);
14
14
  /* add user profile morenda */
@@ -40,6 +40,6 @@ export default function bootstrap() {
40
40
  As soon as response received, auth.on('profile', ...) handlers start to work.
41
41
  It's very important point to build UI for the user.
42
42
  */
43
- auth.profile();
43
+ await auth.profile();
44
44
  }
45
45
  //# sourceMappingURL=bootstrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../client/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,0BAA0B,CAAA;AACjC,OAAO,iCAAiC,CAAA,CAAC,sDAAsD;AAE/F,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAE/B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wDAAwD,CAAA;AAC/F,OAAO,EAAE,cAAc,IAAI,mBAAmB,EAAE,gBAAgB,IAAI,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE5I,OAAO,EAAE,IAAI,EAAE,MAAM,+CAA+C,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAE9D,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,mBAAmB,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAA;IACxD,qBAAqB,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAA;IAExD,8BAA8B;IAC9B,KAAK,CAAC,QAAQ,CAAC;QACb,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAA,qCAAqC;YAC/C,IAAI,EAAE,IAAI,CAAA,iDAAiD;YAC3D,QAAQ,EAAE,aAAa,CAAC,SAAS;YACjC,MAAM,EAAE,GAAG,EAAE;gBACX,QAAQ,CAAC,SAAS,CAAC,CAAA;YACrB,CAAC;SACF;KACF,CAAC,CAAA;IAEF,0BAA0B;IAC1B,KAAK,CAAC,QAAQ,CAAC;QACb,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAA,kCAAkC;YAC5C,IAAI,EAAE,IAAI,CAAA,8CAA8C;YACxD,QAAQ,EAAE,aAAa,CAAC,SAAS;YACjC,MAAM,EAAE,GAAG,EAAE;gBACX,IAAI,CAAC,OAAO,EAAE,CAAA;YAChB,CAAC;SACF;KACF,CAAC,CAAA;IAEF;;;;MAIE;IACF,IAAI,CAAC,OAAO,EAAE,CAAA;AAChB,CAAC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/attribute/grist-editor' /* for register data-grist editor type 'attributes' */\n\nimport { html } from 'lit-html'\n\nimport { navigate, store } from '@operato/shell'\nimport { TOOL_POSITION } from '@operato/layout'\nimport { OxGristEditorPrivilege } from '@operato/app/grist-editor/ox-grist-editor-privilege.js'\nimport { registerEditor as registerGristEditor, registerRenderer as registerGristRenderer, OxGristRendererJson5 } from '@operato/data-grist'\n\nimport { auth } from '@things-factory/auth-base/dist-client/auth.js'\nimport { ADD_MORENDA } from '@things-factory/more-base/client'\n\nexport default function bootstrap() {\n registerGristEditor('privilege', OxGristEditorPrivilege)\n registerGristRenderer('privilege', OxGristRendererJson5)\n\n /* add user profile morenda */\n store.dispatch({\n type: ADD_MORENDA,\n morenda: {\n icon: html` <md-icon>account_circle</md-icon> `,\n name: html` <ox-i18n msgid=\"text.auth profile\"></ox-i18n> `,\n position: TOOL_POSITION.FRONT_END,\n action: () => {\n navigate('profile')\n }\n }\n })\n\n /* add sign-out morenda */\n store.dispatch({\n type: ADD_MORENDA,\n morenda: {\n icon: html` <md-icon>exit_to_app</md-icon> `,\n name: html` <ox-i18n msgid=\"field.sign out\"></ox-i18n> `,\n position: TOOL_POSITION.FRONT_END,\n action: () => {\n auth.signout()\n }\n }\n })\n\n /* \n Get user profile information from server. \n As soon as response received, auth.on('profile', ...) handlers start to work.\n It's very important point to build UI for the user.\n */\n auth.profile()\n}\n"]}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../client/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,0BAA0B,CAAA;AACjC,OAAO,iCAAiC,CAAA,CAAC,sDAAsD;AAE/F,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAE/B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wDAAwD,CAAA;AAC/F,OAAO,EACL,cAAc,IAAI,mBAAmB,EACrC,gBAAgB,IAAI,qBAAqB,EACzC,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,IAAI,EAAE,MAAM,+CAA+C,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAE9D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,SAAS;IACrC,mBAAmB,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAA;IACxD,qBAAqB,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAA;IAExD,8BAA8B;IAC9B,KAAK,CAAC,QAAQ,CAAC;QACb,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAA,qCAAqC;YAC/C,IAAI,EAAE,IAAI,CAAA,iDAAiD;YAC3D,QAAQ,EAAE,aAAa,CAAC,SAAS;YACjC,MAAM,EAAE,GAAG,EAAE;gBACX,QAAQ,CAAC,SAAS,CAAC,CAAA;YACrB,CAAC;SACF;KACF,CAAC,CAAA;IAEF,0BAA0B;IAC1B,KAAK,CAAC,QAAQ,CAAC;QACb,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAA,kCAAkC;YAC5C,IAAI,EAAE,IAAI,CAAA,8CAA8C;YACxD,QAAQ,EAAE,aAAa,CAAC,SAAS;YACjC,MAAM,EAAE,GAAG,EAAE;gBACX,IAAI,CAAC,OAAO,EAAE,CAAA;YAChB,CAAC;SACF;KACF,CAAC,CAAA;IAEF;;;;MAIE;IACF,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;AACtB,CAAC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/attribute/grist-editor' /* for register data-grist editor type 'attributes' */\n\nimport { html } from 'lit-html'\n\nimport { navigate, store } from '@operato/shell'\nimport { TOOL_POSITION } from '@operato/layout'\nimport { OxGristEditorPrivilege } from '@operato/app/grist-editor/ox-grist-editor-privilege.js'\nimport {\n registerEditor as registerGristEditor,\n registerRenderer as registerGristRenderer,\n OxGristRendererJson5\n} from '@operato/data-grist'\n\nimport { auth } from '@things-factory/auth-base/dist-client/auth.js'\nimport { ADD_MORENDA } from '@things-factory/more-base/client'\n\nexport default async function bootstrap() {\n registerGristEditor('privilege', OxGristEditorPrivilege)\n registerGristRenderer('privilege', OxGristRendererJson5)\n\n /* add user profile morenda */\n store.dispatch({\n type: ADD_MORENDA,\n morenda: {\n icon: html` <md-icon>account_circle</md-icon> `,\n name: html` <ox-i18n msgid=\"text.auth profile\"></ox-i18n> `,\n position: TOOL_POSITION.FRONT_END,\n action: () => {\n navigate('profile')\n }\n }\n })\n\n /* add sign-out morenda */\n store.dispatch({\n type: ADD_MORENDA,\n morenda: {\n icon: html` <md-icon>exit_to_app</md-icon> `,\n name: html` <ox-i18n msgid=\"field.sign out\"></ox-i18n> `,\n position: TOOL_POSITION.FRONT_END,\n action: () => {\n auth.signout()\n }\n }\n })\n\n /* \n Get user profile information from server. \n As soon as response received, auth.on('profile', ...) handlers start to work.\n It's very important point to build UI for the user.\n */\n await auth.profile()\n}\n"]}
@@ -99,21 +99,21 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
99
99
  }
100
100
  get formfields() {
101
101
  var _a;
102
- const email = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.email) || '';
103
- // .validationMessage=${String(i18next.t('text.invalid-email'))}
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="email"
110
- type="email"
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=${email}
113
+ .value=${username}
114
114
  autocomplete="off"
115
115
  autocapitalize="off"
116
- ><md-icon slot="leading-icon">mail</md-icon></md-filled-text-field
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">vpn_key</md-icon></md-filled-text-field
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="submit" raised @click=${e => this._onSubmit(e)}>
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">badge</md-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>
@@ -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 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
+ {"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,11 +1,10 @@
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';
6
4
  import '@operato/i18n/ox-i18n.js';
7
5
  import '@operato/i18n/ox-i18n-selector.js';
8
6
  import '@operato/layout/ox-snack-bar.js';
7
+ import '../components/profile-component';
9
8
  import { AbstractAuthPage } from './abstract-auth-page';
10
9
  export declare abstract class AbstractPasswordReset extends AbstractAuthPage {
11
10
  static styles: import("lit").CSSResult[];
@@ -2,15 +2,13 @@ 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';
7
5
  import '@operato/i18n/ox-i18n.js';
8
6
  import '@operato/i18n/ox-i18n-selector.js';
9
7
  import '@operato/layout/ox-snack-bar.js';
8
+ import '../components/profile-component';
10
9
  import { css, html, nothing } from 'lit';
11
10
  import { property, query } from 'lit/decorators.js';
12
11
  import { i18next } from '@operato/i18n';
13
- import { isSafari } from '@operato/utils';
14
12
  import { AUTH_STYLE_SIGN } from '../auth-style-sign';
15
13
  import { generatePasswordPatternHelp, generatePasswordPatternRegExp } from '../utils/password-rule';
16
14
  import { AbstractAuthPage } from './abstract-auth-page';
@@ -56,7 +54,8 @@ export class AbstractPasswordReset extends AbstractAuthPage {
56
54
  this.confirmPass.setAttribute('pattern', val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '[$&]'));
57
55
  }}
58
56
  required
59
- ></md-filled-text-field>
57
+ ><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
58
+ >
60
59
  </div>
61
60
 
62
61
  <div class="field">
@@ -67,7 +66,8 @@ export class AbstractPasswordReset extends AbstractAuthPage {
67
66
  label=${String(i18next.t('field.confirm password'))}
68
67
  autocomplete="off"
69
68
  required
70
- ></md-filled-text-field>
69
+ ><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
70
+ >
71
71
  </div>
72
72
 
73
73
  <md-elevated-button id="submit-button" type="submit" @click=${e => this._onSubmit(e)}>
@@ -93,15 +93,8 @@ export class AbstractPasswordReset extends AbstractAuthPage {
93
93
  </form>
94
94
  </div>
95
95
  </div>
96
- <ox-snack-bar id="snackbar" level="error" .message=${this.message}></ox-snack-bar>
97
96
 
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
- `}
97
+ <ox-snack-bar id="snackbar" level="error" .message=${this.message}></ox-snack-bar>
105
98
  `;
106
99
  }
107
100
  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,wBAAwB,CAAA;AAC/B,OAAO,iCAAiC,CAAA;AACxC,OAAO,0BAA0B,CAAA;AACjC,OAAO,mCAAmC,CAAA;AAC1C,OAAO,iCAAiC,CAAA;AAExC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAA;AACnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEvD,MAAM,OAAgB,qBAAsB,SAAQ,gBAAgB;IAApE;;QAgCU,oBAAe,GAAW,EAAE,CAAA;QAC5B,iBAAY,GAAW,EAAE,CAAA;IAkHnC,CAAC;IA9GC,MAAM;QACJ,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,eAAe,CAAA;QACvD,MAAM,EAAE,0BAA0B,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;QAEjE,OAAO,IAAI,CAAA;;;qBAGM,IAAI;iCACQ,KAAK;sCACA,WAAW;;;;sCAIX,IAAI,CAAC,KAAK;;;sBAG1B,IAAI,CAAC,SAAS;;wBAEZ,CAAC,CAAC,EAAE;YACd,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO;gBAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACzC,CAAC;;uDAE0C,IAAI,CAAC,KAAK,IAAI,EAAE;;;;;wBAK/C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;0BACjC,IAAI,CAAC,eAAe,IAAI,EAAE;kCAClB,IAAI,CAAC,YAAY;;yBAE1B,CAAC,CAAC,EAAE;YACX,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YACxB,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAA;QAC3F,CAAC;;;;;;;;;;wBAUO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;;;;;;0EAMO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;gCAChE,IAAI,CAAC,iBAAiB;;;cAGxC,CAAC,0BAA0B;YAC3B,CAAC,CAAC,IAAI,CAAA;;;;4BAIQ,OAAO,CAAC,QAAQ,IAAI,OAAO;iCACtB,SAAS;8BACZ,CAAC,CAAC,EAAE;gBACZ,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;gBACrB,IAAI,CAAC,MAAM;oBAAE,OAAM;gBAEnB,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;YAChC,CAAC;;uBAEE;YACT,CAAC,CAAC,OAAO;;;;2DAIoC,IAAI,CAAC,OAAO;;QAE/D,QAAQ,EAAE;YACV,CAAC,CAAC,IAAI,CAAA,EAAE;YACR,CAAC,CAAC,IAAI,CAAA;;;;WAIH;KACN,CAAA;IACH,CAAC;IAED,OAAO,CAAC,OAAO;QACb,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACtB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA;QAC9B,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,CAAC,YAAY,EAAE,CAAA;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,YAAY,CAAC;oBAChB,KAAK,EAAE,CAAC,CAAC;iBACV,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,eAAe;QACb,IAAI,CAAC,eAAe,GAAG,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAA;QACnF,IAAI,CAAC,YAAY,GAAG,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACzE,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;IACtB,CAAC;;AAjJM,4BAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;KAqBF;IACD,eAAe;CAChB,AAxBY,CAwBZ;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;mDAAU;AACT;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;oDAAe;AAEd;IAA3B,KAAK,CAAC,mBAAmB,CAAC;8BAAe,WAAW;0DAAA","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"]}
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/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport '@operato/layout/ox-snack-bar.js'\n\nimport '../components/profile-component'\n\nimport { css, html, nothing } from 'lit'\nimport { property, query } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\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-icon slot=\"leading-icon\">password</md-icon></md-filled-text-field\n >\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-icon slot=\"leading-icon\">password</md-icon></md-filled-text-field\n >\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\n <ox-snack-bar id=\"snackbar\" level=\"error\" .message=${this.message}></ox-snack-bar>\n `\n }\n\n updated(changed) {\n super.updated(changed)\n\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"]}
@@ -25,30 +25,31 @@ export class AbstractSign extends AbstractAuthPage {
25
25
  }
26
26
  get formfields() {
27
27
  var _a;
28
- const email = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.email) || '';
28
+ const username = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.username) || '';
29
29
  const autocompletable = this.autocompletable;
30
30
  return html `
31
31
  <input id="redirectTo" type="hidden" name="redirectTo" .value=${this.redirectTo || '/'} />
32
32
 
33
33
  <div class="field">
34
34
  <md-filled-text-field
35
- name="email"
36
- type="email"
37
- label=${String(i18next.t('field.email'))}
35
+ name="username"
36
+ type="text"
37
+ label=${String(i18next.t('field.user-id or email'))}
38
38
  required
39
- .value=${email}
40
- autocomplete=${autocompletable ? "username" : "off"}
39
+ .value=${username}
40
+ autocomplete=${autocompletable ? 'username' : 'off'}
41
41
  autocapitalize="off"
42
+ pattern="^(?:[A-Za-z0-9]*|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,})$"
42
43
  @input=${(e) => {
43
44
  const target = e.target;
44
45
  if (target.validity.typeMismatch) {
45
- target.setCustomValidity(i18next.t('text.invalid-email'));
46
+ target.setCustomValidity(i18next.t('text.invalid-username'));
46
47
  }
47
48
  else {
48
49
  target.setCustomValidity('');
49
50
  }
50
51
  }}
51
- ><md-icon slot="leading-icon">mail</md-icon></md-filled-text-field
52
+ ><md-icon slot="leading-icon">id_card</md-icon></md-filled-text-field
52
53
  >
53
54
  </div>
54
55
  <div class="field">
@@ -56,14 +57,14 @@ export class AbstractSign extends AbstractAuthPage {
56
57
  name="password"
57
58
  type="password"
58
59
  label=${String(i18next.t('field.password'))}
59
- autocomplete=${autocompletable ? "current-password" : "off"}
60
+ autocomplete=${autocompletable ? 'current-password' : 'off'}
60
61
  required
61
- ><md-icon slot="leading-icon">vpn_key</md-icon></md-filled-text-field
62
+ ><md-icon slot="leading-icon">password</md-icon></md-filled-text-field
62
63
  >
63
64
  </div>
64
65
 
65
66
  <div class="submit-buttons-container">
66
- <md-elevated-button class="submit-button" type="submit" raised @click=${e => this._onSubmit(e)}>
67
+ <md-elevated-button class="submit-button" type="button" raised @click=${e => this._onSubmit(e)}>
67
68
  <ox-i18n msgid="field.${this.pageName}"> </ox-i18n>
68
69
  </md-elevated-button>
69
70
  ${isAvailableWebauthn
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-sign.js","sourceRoot":"","sources":["../../client/components/abstract-sign.ts"],"names":[],"mappings":"AAAA,OAAO,0BAA0B,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,MAAM,mBAAmB,GAAG,qBAAqB,IAAI,MAAM,CAAA;AAe3D,MAAM,OAAgB,YAAa,SAAQ,gBAAgB;IACzD,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;IACtB,CAAC;IAED,OAAO,CAAC,OAAO;QACb,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAEtB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,CAAC,YAAY,EAAE,CAAA;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,YAAY,CAAC;oBAChB,KAAK,EAAE,OAAO;oBACd,KAAK,EAAE,CAAC,CAAC;iBACV,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU;;QACZ,MAAM,KAAK,GAAG,CAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,KAAK,KAAI,EAAE,CAAA;QACpC,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAA;QAE5C,OAAO,IAAI,CAAA;sEACuD,IAAI,CAAC,UAAU,IAAI,GAAG;;;;;;kBAM1E,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;;mBAE/B,KAAK;yBACC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK;;mBAE1C,CAAC,CAAQ,EAAE,EAAE;YACpB,MAAM,MAAM,GAAG,CAAC,CAAC,MAA0B,CAAA;YAC3C,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;gBACjC,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;YAC3D,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;;;;;;;;kBAQO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;yBAC5B,eAAe,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK;;;;;;;gFAOW,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;kCACpE,IAAI,CAAC,QAAQ;;UAErC,mBAAmB;YACnB,CAAC,CAAC,IAAI,CAAA,+CAA+C,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,0BAA0B;YAC3G,CAAC,CAAC,OAAO;;KAEd,CAAA;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,iCAAiC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;YACtF,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAA;YACxD,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,uBAAuB,EAAE;gBACxD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;aACpC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;YAE1B,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,EAAE,WAAW,EAAE,GAAG,YAAY,CAAA;gBAEpC,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAA;gBACpC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC;oBACL,KAAK,EAAE,OAAO;oBACd,OAAO,EAAE,YAAY,CAAC,OAAO;iBAC9B,CAAC,CAAA;YACJ,CAAC;QAEH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC;gBACL,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;aACtD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;CACF","sourcesContent":["import '@operato/i18n/ox-i18n.js'\n\nimport { html, nothing } from 'lit'\nimport { startAuthentication } from '@simplewebauthn/browser'\n\nimport { i18next } from '@operato/i18n'\nimport { notify } from '@operato/layout'\n\nimport { AbstractAuthPage } from './abstract-auth-page.js'\n\nconst isAvailableWebauthn = 'PublicKeyCredential' in window\n\ninterface AssertionResponse {\n id: string\n rawId?: number[]\n response: {\n authenticatorData: string\n clientDataJSON: string\n signature: string\n userHandle: string | null\n }\n type: PublicKeyCredentialType\n authenticatorAttachment?: AuthenticatorAttachment\n}\n\nexport abstract class AbstractSign extends AbstractAuthPage {\n async submit() {\n this.formEl.submit()\n }\n\n updated(changed) {\n super.updated(changed)\n\n if (changed.has('message')) {\n if (!this.message) {\n this.hideSnackbar()\n } else {\n this.showSnackbar({\n level: 'error',\n timer: -1\n })\n }\n }\n }\n\n get formfields() {\n const email = this.data?.email || ''\n const autocompletable = this.autocompletable\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=${autocompletable ? \"username\" : \"off\"}\n autocapitalize=\"off\"\n @input=${(e: Event) => {\n const target = e.target as HTMLInputElement\n if (target.validity.typeMismatch) {\n target.setCustomValidity(i18next.t('text.invalid-email'))\n } else {\n target.setCustomValidity('')\n }\n }}\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=${autocompletable ? \"current-password\" : \"off\"}\n required\n ><md-icon slot=\"leading-icon\">vpn_key</md-icon></md-filled-text-field\n >\n </div>\n\n <div class=\"submit-buttons-container\">\n <md-elevated-button class=\"submit-button\" type=\"submit\" raised @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"field.${this.pageName}\"> </ox-i18n>\n </md-elevated-button>\n ${isAvailableWebauthn\n ? html` <md-icon class=\"fingerprint\" raised @click=${e => this.authenticateUser()}> fingerprint </md-icon>`\n : nothing}\n </div>\n `\n }\n\n async authenticateUser() {\n try {\n const options = await fetch('/auth/signin-webauthn/challenge').then(res => res.json())\n const assertionResp = await startAuthentication(options)\n const verification = await fetch('/auth/signin-webauthn', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(assertionResp)\n }).then(res => res.json())\n\n if (verification.verified) {\n const { redirectURL } = verification\n \n if (redirectURL) {\n window.location.href = redirectURL\n }\n } else {\n notify({\n level: 'error',\n message: verification.message\n })\n }\n \n } catch (error) {\n notify({\n level: 'error',\n message: i18next.t('error.authn verification failed')\n })\n }\n }\n}\n"]}
1
+ {"version":3,"file":"abstract-sign.js","sourceRoot":"","sources":["../../client/components/abstract-sign.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/i18n/ox-i18n.js'\n\nimport { html, nothing } from 'lit'\nimport { startAuthentication } from '@simplewebauthn/browser'\n\nimport { i18next } from '@operato/i18n'\nimport { notify } from '@operato/layout'\n\nimport { AbstractAuthPage } from './abstract-auth-page.js'\n\nconst isAvailableWebauthn = 'PublicKeyCredential' in window\n\ninterface AssertionResponse {\n id: string\n rawId?: number[]\n response: {\n authenticatorData: string\n clientDataJSON: string\n signature: string\n userHandle: string | null\n }\n type: PublicKeyCredentialType\n authenticatorAttachment?: AuthenticatorAttachment\n}\n\nexport abstract class AbstractSign extends AbstractAuthPage {\n async submit() {\n this.formEl.submit()\n }\n\n updated(changed) {\n super.updated(changed)\n\n if (changed.has('message')) {\n if (!this.message) {\n this.hideSnackbar()\n } else {\n this.showSnackbar({\n level: 'error',\n timer: -1\n })\n }\n }\n }\n\n get formfields() {\n const username = this.data?.username || ''\n const autocompletable = this.autocompletable\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=${autocompletable ? 'username' : 'off'}\n autocapitalize=\"off\"\n pattern=\"^(?:[A-Za-z0-9]*|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,})$\"\n @input=${(e: Event) => {\n const target = e.target as HTMLInputElement\n if (target.validity.typeMismatch) {\n target.setCustomValidity(i18next.t('text.invalid-username'))\n } else {\n target.setCustomValidity('')\n }\n }}\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=${autocompletable ? 'current-password' : 'off'}\n required\n ><md-icon slot=\"leading-icon\">password</md-icon></md-filled-text-field\n >\n </div>\n\n <div class=\"submit-buttons-container\">\n <md-elevated-button class=\"submit-button\" type=\"button\" raised @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"field.${this.pageName}\"> </ox-i18n>\n </md-elevated-button>\n ${isAvailableWebauthn\n ? html` <md-icon class=\"fingerprint\" raised @click=${e => this.authenticateUser()}> fingerprint </md-icon>`\n : nothing}\n </div>\n `\n }\n\n async authenticateUser() {\n try {\n const options = await fetch('/auth/signin-webauthn/challenge').then(res => res.json())\n const assertionResp = await startAuthentication(options)\n const verification = await fetch('/auth/signin-webauthn', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(assertionResp)\n }).then(res => res.json())\n\n if (verification.verified) {\n const { redirectURL } = verification\n\n if (redirectURL) {\n window.location.href = redirectURL\n }\n } else {\n notify({\n level: 'error',\n message: verification.message\n })\n }\n } catch (error) {\n notify({\n level: 'error',\n message: i18next.t('error.authn verification failed')\n })\n }\n }\n}\n"]}
@@ -8,7 +8,7 @@ declare const ContactUs_base: (new (...args: any[]) => LitElement) & typeof LitE
8
8
  export declare class ContactUs extends ContactUs_base {
9
9
  static get styles(): import("lit").CSSResult[];
10
10
  dialog: HTMLElement & {
11
- open: boolean;
11
+ show: () => void;
12
12
  };
13
13
  subjectInput: HTMLInputElement;
14
14
  senderInput: HTMLInputElement;