@things-factory/auth-ui 8.0.0-beta.1 → 8.0.0-beta.2

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 (59) hide show
  1. package/package.json +4 -4
  2. package/client/auth-style-sign.ts +0 -194
  3. package/client/bootstrap.ts +0 -51
  4. package/client/components/abstract-auth-page.ts +0 -301
  5. package/client/components/abstract-password-reset.ts +0 -163
  6. package/client/components/abstract-sign.ts +0 -127
  7. package/client/components/change-password.ts +0 -153
  8. package/client/components/contact-us.ts +0 -116
  9. package/client/components/create-domain-popup.ts +0 -141
  10. package/client/components/create-role.ts +0 -123
  11. package/client/components/create-user.ts +0 -117
  12. package/client/components/credential-manager.ts +0 -64
  13. package/client/components/delete-user-popup.ts +0 -117
  14. package/client/components/domain-switch.ts +0 -127
  15. package/client/components/invite-customer.ts +0 -104
  16. package/client/components/invite-user.ts +0 -104
  17. package/client/components/my-login-history.ts +0 -101
  18. package/client/components/ownership-transfer-popup.ts +0 -110
  19. package/client/components/partner-info-card.ts +0 -89
  20. package/client/components/partner-role-editor.ts +0 -153
  21. package/client/components/profile-component.ts +0 -392
  22. package/client/components/role-edit-form.ts +0 -92
  23. package/client/components/role-privilege-editor.ts +0 -268
  24. package/client/components/role-selector.ts +0 -102
  25. package/client/components/user-role-editor.ts +0 -499
  26. package/client/constants/application.ts +0 -9
  27. package/client/constants/index.ts +0 -1
  28. package/client/entries/auth/activate.ts +0 -272
  29. package/client/entries/auth/checkin.ts +0 -190
  30. package/client/entries/auth/forgot-password.ts +0 -112
  31. package/client/entries/auth/reset-password.ts +0 -22
  32. package/client/entries/auth/result.ts +0 -193
  33. package/client/entries/auth/signin.ts +0 -18
  34. package/client/entries/auth/signup.ts +0 -115
  35. package/client/entries/auth/unlock-user.ts +0 -22
  36. package/client/entries/oauth2/oauth2-decision-error-page.ts +0 -50
  37. package/client/entries/oauth2/oauth2-decision-page.ts +0 -196
  38. package/client/entries/public/home.ts +0 -246
  39. package/client/index.ts +0 -124
  40. package/client/pages/app-binding/app-binding.ts +0 -423
  41. package/client/pages/app-binding/app-bindings.ts +0 -171
  42. package/client/pages/appliance/appliance.ts +0 -452
  43. package/client/pages/appliance/home.ts +0 -177
  44. package/client/pages/appliance/register.ts +0 -183
  45. package/client/pages/application/application.ts +0 -428
  46. package/client/pages/application/applications.ts +0 -182
  47. package/client/pages/application/register.ts +0 -211
  48. package/client/pages/attribute/attribute-set-item-list.ts +0 -237
  49. package/client/pages/attribute/attribute-set-management.ts +0 -282
  50. package/client/pages/auth-provider/auth-provider-management.ts +0 -381
  51. package/client/pages/domain/domain-management.ts +0 -410
  52. package/client/pages/partner/partner-management.ts +0 -112
  53. package/client/pages/profile.ts +0 -32
  54. package/client/pages/role/role-management.ts +0 -134
  55. package/client/pages/user/user-management.ts +0 -223
  56. package/client/route.ts +0 -67
  57. package/client/themes/auth-theme.css +0 -65
  58. package/client/utils/password-rule.ts +0 -37
  59. package/server/index.ts +0 -0
@@ -1,410 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
-
3
- import '@operato/data-grist/ox-grist.js'
4
- import '@operato/data-grist/ox-filters-form.js'
5
- import '@operato/context/ox-context-page-toolbar.js'
6
- import '@operato/attribute/ox-attribute-view.js'
7
- import '../../components/create-domain-popup'
8
-
9
- import gql from 'graphql-tag'
10
- import { css, html } from 'lit'
11
- import { customElement, property, query } from 'lit/decorators.js'
12
- import moment from '@operato/moment-timezone-es'
13
- import { connect } from 'pwa-helpers/connect-mixin'
14
-
15
- import { DataGrist } from '@operato/data-grist/ox-grist.js'
16
- import { client } from '@operato/graphql'
17
- import { i18next, localize } from '@operato/i18n'
18
- import { openPopup } from '@operato/layout'
19
- import { PageView, store } from '@operato/shell'
20
- import { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
21
- import { isMobileDevice } from '@operato/utils'
22
- import { p13n } from '@operato/p13n'
23
- import { FetchOption } from '@operato/data-grist'
24
-
25
- function getSystemTimeZone(): string {
26
- try {
27
- const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
28
- if (!timeZone) {
29
- throw new Error('Unable to resolve timeZone')
30
- }
31
- return timeZone
32
- } catch (e) {
33
- console.warn('Failed to get system timeZone, falling back to UTC.', e)
34
- return 'UTC'
35
- }
36
- }
37
-
38
- const DEFAULT_TZ = getSystemTimeZone()
39
- const TIMEZONE_OPTIONS = ['', DEFAULT_TZ, ...moment.tz.names().filter(tz => tz !== DEFAULT_TZ)]
40
-
41
- @customElement('domain-management')
42
- export class DomainManagement extends connect(store)(p13n(localize(i18next)(PageView))) {
43
- static styles = [
44
- CommonGristStyles,
45
- CommonHeaderStyles,
46
- ScrollbarStyles,
47
- css`
48
- :host {
49
- display: flex;
50
- flex-direction: column;
51
-
52
- overflow: hidden;
53
- }
54
-
55
- ox-grist {
56
- overflow-y: auto;
57
- flex: 1;
58
- }
59
- `
60
- ]
61
-
62
- @property({ type: Boolean }) active: boolean = false
63
- @property({ type: Object }) config: any
64
- @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'
65
-
66
- @query('ox-grist') private grist!: DataGrist
67
-
68
- get context() {
69
- return {
70
- title: i18next.t('text.domain management'),
71
- search: {
72
- handler: (search: string) => {
73
- this.grist.searchText = search
74
- },
75
- value: this.grist?.searchText || ''
76
- },
77
- filter: {
78
- handler: () => {
79
- this.grist.toggleHeadroom()
80
- }
81
- },
82
- actions: [
83
- {
84
- title: i18next.t('button.add'),
85
- action: this.onCreateDomain.bind(this),
86
- icon: 'add'
87
- },
88
- {
89
- title: i18next.t('button.save'),
90
- action: this.onUpdateDomains.bind(this),
91
- icon: 'save'
92
- }
93
- ],
94
- toolbar: false
95
- }
96
- }
97
-
98
- render() {
99
- return html`
100
- <ox-grist
101
- .mode=${this.mode}
102
- .config=${this.config}
103
- .fetchHandler=${this.fetchHandler.bind(this)}
104
- .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}
105
- >
106
- <div slot="headroom" class="header">
107
- <ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
108
- </div>
109
-
110
- <ox-grist-personalizer slot="setting"></ox-grist-personalizer>
111
- </ox-grist>
112
- `
113
- }
114
-
115
- async pageInitialized() {
116
- this.config = {
117
- rows: {
118
- appendable: false
119
- },
120
- columns: [
121
- { type: 'gutter', gutterName: 'sequence' },
122
- {
123
- type: 'gutter',
124
- gutterName: 'button',
125
- icon: 'assignment',
126
- title: i18next.t('title.open attributes view'),
127
- handlers: {
128
- click: async (columns, data, column, record, rowIndex) => {
129
- const attributeSet = await this.getAttributeSetForDomain()
130
-
131
- openPopup(
132
- html`
133
- <ox-attribute-view
134
- .attributeSet=${attributeSet}
135
- .value=${record.attributes}
136
- style="background-color: white;"
137
- ></ox-attribute-view>
138
- `,
139
- {
140
- backdrop: true,
141
- size: 'large',
142
- title: record.name + ' ' + i18next.t('title.attributes')
143
- }
144
- )
145
- }
146
- }
147
- },
148
- {
149
- type: 'gutter',
150
- gutterName: 'button',
151
- icon: 'domain',
152
- title: i18next.t('title.move to this domain'),
153
- handlers: {
154
- click: (_columns, _data, _column, record, _rowIndex) => {
155
- if (record.id) {
156
- const subdomain = record.subdomain
157
- location.pathname = `/domain/${subdomain}/users`
158
- }
159
- }
160
- }
161
- },
162
- {
163
- type: 'string',
164
- name: 'name',
165
- header: i18next.t('field.name'),
166
- record: {
167
- editable: false
168
- },
169
- filter: 'search',
170
- sortable: true,
171
- width: 200
172
- },
173
- {
174
- type: 'string',
175
- name: 'description',
176
- header: i18next.t('field.description'),
177
- record: {
178
- editable: true
179
- },
180
- filter: 'search',
181
- width: 200
182
- },
183
- {
184
- type: 'string',
185
- name: 'subdomain',
186
- header: i18next.t('field.subdomain'),
187
- record: {
188
- editable: false
189
- },
190
- filter: 'search',
191
- width: 200
192
- },
193
- {
194
- type: 'resource-object',
195
- name: 'parent',
196
- header: i18next.t('field.parent-domain'),
197
- record: {
198
- editable: true,
199
- options: {
200
- title: i18next.t('text.select domain'),
201
- queryName: 'domains',
202
- nameField: 'name',
203
- descriptionField: 'description',
204
- select: [
205
- { name: 'id', hidden: true },
206
- { name: 'name', header: i18next.t('field.name'), filter: 'search' },
207
- { name: 'description', header: i18next.t('field.description'), filter: 'search' }
208
- ],
209
- list: { fields: ['name', 'description'] }
210
- }
211
- },
212
- width: 140
213
- },
214
- {
215
- type: 'resource-object',
216
- name: 'ownerUser',
217
- header: i18next.t('field.owner-user'),
218
- record: {
219
- editable: true,
220
- options: {
221
- title: i18next.t('title.lookup user'),
222
- queryName: 'users',
223
- nameField: 'name',
224
- descriptionField: 'email',
225
- select: [
226
- { name: 'id', hidden: true },
227
- { name: 'name', header: i18next.t('field.name'), filter: 'search' },
228
- { name: 'email', header: i18next.t('field.email'), filter: 'search' }
229
- ],
230
- filters: [{ name: 'userType', operator: 'eq', value: 'user' }],
231
- list: { fields: ['name', 'email'] }
232
- }
233
- },
234
- width: 140
235
- },
236
- {
237
- type: 'select',
238
- name: 'extType',
239
- header: i18next.t('field.type'),
240
- record: {
241
- editable: true,
242
- options: []
243
- },
244
- width: 70
245
- },
246
- {
247
- type: 'select',
248
- name: 'timezone',
249
- header: i18next.t('field.timezone'),
250
- record: {
251
- editable: true,
252
- options: TIMEZONE_OPTIONS
253
- },
254
- width: 120
255
- },
256
- {
257
- type: 'attributes',
258
- name: 'attributes',
259
- header: i18next.t('field.attributes'),
260
- record: {
261
- editable: true,
262
- options: async () => {
263
- return {
264
- objectified: true,
265
- attributeSet: await this.getAttributeSetForDomain()
266
- }
267
- }
268
- },
269
- width: 120
270
- },
271
- {
272
- type: 'datetime',
273
- name: 'updatedAt',
274
- header: i18next.t('field.updated_at'),
275
- width: 180
276
- }
277
- ]
278
- }
279
- }
280
-
281
- async pageUpdated(changes, lifecycle) {
282
- if (this.active) {
283
- await this.updateComplete
284
-
285
- this.grist.fetch()
286
- }
287
- }
288
-
289
- async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) {
290
- const response = await client.query({
291
- query: gql`
292
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
293
- domains(filters: $filters, pagination: $pagination, sortings: $sortings) {
294
- items {
295
- id
296
- name
297
- description
298
- subdomain
299
- parent {
300
- id
301
- name
302
- }
303
- ownerUser {
304
- id
305
- name
306
- email
307
- }
308
- extType
309
- timezone
310
- attributes
311
- updatedAt
312
- }
313
- total
314
- }
315
- }
316
- `,
317
- variables: {
318
- filters,
319
- pagination: { page, limit },
320
- sortings
321
- }
322
- })
323
-
324
- return {
325
- total: response.data.domains.total || 0,
326
- records: response.data.domains.items || []
327
- }
328
- }
329
-
330
- async onUpdateDomains() {
331
- let patches = this.grist.dirtyRecords
332
-
333
- if (patches && patches.length) {
334
- patches = patches.map(domain => {
335
- let patchField = domain.id ? { id: domain.id } : {}
336
- const dirtyFields = domain.__dirtyfields__
337
- for (let key in dirtyFields) {
338
- if (key == 'ownerUser') {
339
- const ownerUser = dirtyFields[key].after
340
- patchField['owner'] = ownerUser.id || ''
341
- } else {
342
- patchField[key] = dirtyFields[key].after
343
- }
344
- }
345
-
346
- return {
347
- ...patchField
348
- }
349
- })
350
-
351
- const response = await client.mutate({
352
- mutation: gql`
353
- mutation updateDomains($patches: [DomainPatch!]!) {
354
- updateDomains(patches: $patches)
355
- }
356
- `,
357
- variables: { patches }
358
- })
359
-
360
- if (!response.errors) {
361
- this.grist.fetch()
362
- return this.showToast(i18next.t('text.updated_successfully'))
363
- }
364
- }
365
- }
366
-
367
- async onCreateDomain() {
368
- openPopup(
369
- html`
370
- <create-domain-popup
371
- @fetch-data=${async () => {
372
- this.grist.fetch()
373
- }}
374
- ></create-domain-popup>
375
- `,
376
- {
377
- size: 'small',
378
- title: `${i18next.t('title.create_domain')}`
379
- }
380
- )
381
- }
382
-
383
- async getAttributeSetForDomain() {
384
- const response = await client.query({
385
- query: gql`
386
- query {
387
- attributeSet: attributeSetByEntity(entity: "Domain") {
388
- entity
389
- description
390
- items {
391
- name
392
- description
393
- tag
394
- type
395
- active
396
- hidden
397
- options
398
- }
399
- }
400
- }
401
- `
402
- })
403
-
404
- return response.data?.attributeSet || {}
405
- }
406
-
407
- showToast(message) {
408
- document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))
409
- }
410
- }
@@ -1,112 +0,0 @@
1
- import '@things-factory/component-ui'
2
- import '../../components/partner-info-card'
3
- import '../../components/partner-role-editor'
4
- import '../../components/invite-customer'
5
-
6
- import gql from 'graphql-tag'
7
- import { css, html } from 'lit'
8
- import { customElement, property } from 'lit/decorators.js'
9
- import { connect } from 'pwa-helpers/connect-mixin.js'
10
-
11
- import { client, gqlContext } from '@operato/graphql'
12
- import { i18next } from '@operato/i18n'
13
- import { PageView, store } from '@operato/shell'
14
-
15
- @customElement('partner-management')
16
- class PartnerManagement extends connect(store)(PageView) {
17
- static styles = [
18
- css`
19
- :host {
20
- display: flex;
21
- flex-direction: column;
22
- background-color: var(--md-sys-color-background);
23
- padding: var(--spacing-large);
24
-
25
- overflow: auto;
26
- }
27
- h2 {
28
- margin: var(--title-margin);
29
- font: var(--title-font);
30
- color: var(--title-text-color);
31
- }
32
- .role-editor {
33
- flex: 1;
34
- }
35
- `
36
- ]
37
-
38
- @property({ type: Array }) customers: any[] = []
39
- @property({ type: Array }) vendors: any[] = []
40
-
41
- get context() {
42
- return {
43
- title: `${i18next.t('title.partners')}`,
44
- help: 'operato-hub/partners'
45
- }
46
- }
47
-
48
- render() {
49
- const data = {
50
- [i18next.t('label.customers')]: this.customers || [],
51
- [i18next.t('label.vendors')]: this.vendors || []
52
- }
53
-
54
- return html`
55
- <h2>partners</h2>
56
-
57
- <quick-find-list
58
- .data="${data}"
59
- .contentRenderer="${(item, currentTabKey) => html`
60
- ${currentTabKey === i18next.t('label.customers')
61
- ? html`
62
- <partner-role-editor
63
- class="role-editor"
64
- .customer="${item}"
65
- @contractTerminated="${this.refreshPartners.bind(this)}"
66
- ></partner-role-editor>
67
- `
68
- : html`<partner-info-card .partner="${item}"></partner-info-card>`}
69
- `}"
70
- >
71
- </quick-find-list>
72
-
73
- <invite-customer
74
- .customers=${this.customers || []}
75
- @invitationCompleted="${this.refreshPartners.bind(this)}"
76
- ></invite-customer>
77
- `
78
- }
79
-
80
- pageUpdated() {
81
- if (this.active) {
82
- this.refreshPartners()
83
- } else {
84
- /* this page is deactivated */
85
- }
86
- }
87
-
88
- async refreshPartners() {
89
- const response = await client.query({
90
- query: gql`
91
- query {
92
- customers {
93
- id
94
- name
95
- description
96
- }
97
- vendors {
98
- id
99
- name
100
- description
101
- }
102
- }
103
- `,
104
- context: gqlContext()
105
- })
106
-
107
- if (!response.errors?.length) {
108
- this.customers = response.data.customers
109
- this.vendors = response.data.vendors
110
- }
111
- }
112
- }
@@ -1,32 +0,0 @@
1
- import '../components/profile-component'
2
-
3
- import { css, html } from 'lit'
4
- import { customElement } from 'lit/decorators.js'
5
-
6
- import { i18next, localize } from '@operato/i18n'
7
- import { PageView } from '@operato/shell'
8
- import { ScrollbarStyles } from '@operato/styles'
9
-
10
- @customElement('auth-profile')
11
- export class AuthProfile extends localize(i18next)(PageView) {
12
- static styles = [
13
- ScrollbarStyles,
14
- css`
15
- :host {
16
- display: block;
17
- background-color: var(--md-sys-color-background);
18
- overflow-y: auto;
19
- }
20
- `
21
- ]
22
-
23
- get context() {
24
- return {
25
- title: i18next.t('text.auth profile')
26
- }
27
- }
28
-
29
- render() {
30
- return html` <profile-component></profile-component> `
31
- }
32
- }
@@ -1,134 +0,0 @@
1
- import '@things-factory/component-ui'
2
- import '../../components/create-role'
3
- import '../../components/role-edit-form'
4
- import '../../components/role-privilege-editor'
5
-
6
- import gql from 'graphql-tag'
7
- import { css, html } from 'lit'
8
- import { customElement, property, query } from 'lit/decorators.js'
9
- import { connect } from 'pwa-helpers/connect-mixin.js'
10
-
11
- import { client, gqlContext } from '@operato/graphql'
12
- import { i18next } from '@operato/i18n'
13
- import { InheritedValueType, PageView, store } from '@operato/shell'
14
-
15
- @customElement('role-management')
16
- class RoleManagement extends connect(store)(PageView) {
17
- static styles = [
18
- css`
19
- :host {
20
- display: flex;
21
- flex-direction: column;
22
- background-color: var(--md-sys-color-background);
23
- padding: var(--spacing-large);
24
- overflow: auto;
25
- }
26
-
27
- [subtitle] {
28
- padding: var(--subtitle-padding);
29
- font: var(--subtitle-font);
30
- color: var(--subtitle-text-color);
31
-
32
- text-transform: capitalize;
33
- }
34
-
35
- input {
36
- display: block;
37
- }
38
-
39
- #roles-privileges {
40
- flex: 1;
41
- display: flex;
42
- margin-top: var(--spacing-medium);
43
- max-width: var(--content-container-max-width);
44
- flex-direction: row;
45
- overflow: auto;
46
- border-top: var(--border-dim-color);
47
- }
48
- `
49
- ]
50
-
51
- @property({ type: String }) title: string = ''
52
- @property({ type: Object }) role: any
53
- @property({ type: Array }) roles: any[] = []
54
- @property({ type: Object }) updateRoleObj: any
55
-
56
- get context() {
57
- return {
58
- title: i18next.t('text.role_management'),
59
- help: 'auth/roles'
60
- }
61
- }
62
-
63
- render() {
64
- const data = {
65
- roles: this.roles || []
66
- }
67
-
68
- return html`
69
- <create-role
70
- @fetch-roles=${async () => {
71
- this.roles = await this.fetchRoles()
72
- }}
73
- ></create-role>
74
-
75
- <div subtitle>${i18next.t('text.registered roles')}</div>
76
- <div id="roles-privileges">
77
- <quick-find-list
78
- .data="${data}"
79
- .openHeaderRenderer=${role => html`
80
- <role-edit-form .role="${role}" @roleChanged="${e => (this.updateRoleObj = e.detail)}"></role-edit-form>
81
- `}
82
- .contentRenderer="${(role, _currentTabKey) => html`
83
- <role-privilege-editor
84
- .updateRoleObj=${this.updateRoleObj || {}}
85
- .role=${role}
86
- @fetch-roles=${async () => {
87
- this.roles = await this.fetchRoles()
88
- await this.updateComplete
89
- this.quickFindList.openByKey(role.id)
90
- }}
91
- ></role-privilege-editor>
92
- `}"
93
- ></quick-find-list>
94
- </div>
95
- `
96
- }
97
-
98
- @query('quick-find-list') quickFindList!: HTMLElement & { openByKey: (roleId: string) => void }
99
-
100
- async pageUpdated(changes, lifecycle, before) {
101
- if (this.active) {
102
- this.roles = await this.fetchRoles()
103
- this.role = this.roles && this.roles[0]
104
- }
105
- }
106
-
107
- async fetchRoles() {
108
- const response = await client.query({
109
- query: gql`
110
- query roles($sortings: [Sorting!], $inherited: InheritedValueType) {
111
- roles(sortings: $sortings, inherited: $inherited) {
112
- items {
113
- id
114
- name
115
- description
116
- privileges {
117
- id
118
- name
119
- }
120
- }
121
- total
122
- }
123
- }
124
- `,
125
- variables: {
126
- sortings: [{ name: 'name' }],
127
- inherited: InheritedValueType.Include
128
- },
129
- context: gqlContext()
130
- })
131
-
132
- return response.data.roles.items
133
- }
134
- }