@things-factory/auth-ui 8.0.0 → 9.0.0-beta.3

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 (99) hide show
  1. package/dist-client/components/abstract-auth-page.js +10 -10
  2. package/dist-client/components/abstract-auth-page.js.map +1 -1
  3. package/dist-client/components/abstract-password-reset.d.ts +1 -2
  4. package/dist-client/components/abstract-password-reset.js +7 -14
  5. package/dist-client/components/abstract-password-reset.js.map +1 -1
  6. package/dist-client/components/abstract-sign.js +12 -11
  7. package/dist-client/components/abstract-sign.js.map +1 -1
  8. package/dist-client/components/contact-us.d.ts +1 -1
  9. package/dist-client/components/contact-us.js +10 -7
  10. package/dist-client/components/contact-us.js.map +1 -1
  11. package/dist-client/components/create-user.js +28 -5
  12. package/dist-client/components/create-user.js.map +1 -1
  13. package/dist-client/components/invite-user.js +19 -11
  14. package/dist-client/components/invite-user.js.map +1 -1
  15. package/dist-client/components/ownership-transfer-popup.js +3 -3
  16. package/dist-client/components/ownership-transfer-popup.js.map +1 -1
  17. package/dist-client/components/profile-component.d.ts +5 -1
  18. package/dist-client/components/profile-component.js +64 -4
  19. package/dist-client/components/profile-component.js.map +1 -1
  20. package/dist-client/components/role-privilege-editor.js +2 -1
  21. package/dist-client/components/role-privilege-editor.js.map +1 -1
  22. package/dist-client/components/user-role-editor.js +18 -18
  23. package/dist-client/components/user-role-editor.js.map +1 -1
  24. package/dist-client/entries/auth/checkin.js +1 -1
  25. package/dist-client/entries/auth/checkin.js.map +1 -1
  26. package/dist-client/entries/auth/forgot-password.js +11 -2
  27. package/dist-client/entries/auth/forgot-password.js.map +1 -1
  28. package/dist-client/entries/auth/signup.js +13 -7
  29. package/dist-client/entries/auth/signup.js.map +1 -1
  30. package/dist-client/index.js +1 -1
  31. package/dist-client/index.js.map +1 -1
  32. package/dist-client/pages/user/user-management.d.ts +5 -1
  33. package/dist-client/pages/user/user-management.js +6 -7
  34. package/dist-client/pages/user/user-management.js.map +1 -1
  35. package/dist-client/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +12 -12
  37. package/translations/en.json +6 -2
  38. package/translations/ja.json +6 -2
  39. package/translations/ko.json +6 -2
  40. package/translations/ms.json +6 -2
  41. package/translations/zh.json +6 -2
  42. package/client/auth-style-sign.ts +0 -194
  43. package/client/bootstrap.ts +0 -51
  44. package/client/components/abstract-auth-page.ts +0 -301
  45. package/client/components/abstract-password-reset.ts +0 -168
  46. package/client/components/abstract-sign.ts +0 -127
  47. package/client/components/change-password.ts +0 -153
  48. package/client/components/contact-us.ts +0 -113
  49. package/client/components/create-domain-popup.ts +0 -141
  50. package/client/components/create-role.ts +0 -123
  51. package/client/components/create-user.ts +0 -95
  52. package/client/components/credential-manager.ts +0 -64
  53. package/client/components/delete-user-popup.ts +0 -117
  54. package/client/components/domain-switch.ts +0 -127
  55. package/client/components/invite-customer.ts +0 -104
  56. package/client/components/invite-user.ts +0 -96
  57. package/client/components/my-login-history.ts +0 -101
  58. package/client/components/ownership-transfer-popup.ts +0 -110
  59. package/client/components/partner-info-card.ts +0 -89
  60. package/client/components/partner-role-editor.ts +0 -153
  61. package/client/components/profile-component.ts +0 -332
  62. package/client/components/role-edit-form.ts +0 -92
  63. package/client/components/role-privilege-editor.ts +0 -267
  64. package/client/components/role-selector.ts +0 -102
  65. package/client/components/user-role-editor.ts +0 -499
  66. package/client/constants/application.ts +0 -9
  67. package/client/constants/index.ts +0 -1
  68. package/client/entries/auth/activate.ts +0 -272
  69. package/client/entries/auth/checkin.ts +0 -190
  70. package/client/entries/auth/forgot-password.ts +0 -103
  71. package/client/entries/auth/reset-password.ts +0 -22
  72. package/client/entries/auth/result.ts +0 -193
  73. package/client/entries/auth/signin.ts +0 -18
  74. package/client/entries/auth/signup.ts +0 -109
  75. package/client/entries/auth/unlock-user.ts +0 -22
  76. package/client/entries/oauth2/oauth2-decision-error-page.ts +0 -50
  77. package/client/entries/oauth2/oauth2-decision-page.ts +0 -196
  78. package/client/entries/public/home.ts +0 -246
  79. package/client/index.ts +0 -124
  80. package/client/pages/app-binding/app-binding.ts +0 -423
  81. package/client/pages/app-binding/app-bindings.ts +0 -171
  82. package/client/pages/appliance/appliance.ts +0 -452
  83. package/client/pages/appliance/home.ts +0 -177
  84. package/client/pages/appliance/register.ts +0 -183
  85. package/client/pages/application/application.ts +0 -428
  86. package/client/pages/application/applications.ts +0 -182
  87. package/client/pages/application/register.ts +0 -211
  88. package/client/pages/attribute/attribute-set-item-list.ts +0 -237
  89. package/client/pages/attribute/attribute-set-management.ts +0 -282
  90. package/client/pages/auth-provider/auth-provider-management.ts +0 -381
  91. package/client/pages/domain/domain-management.ts +0 -410
  92. package/client/pages/partner/partner-management.ts +0 -112
  93. package/client/pages/profile.ts +0 -32
  94. package/client/pages/role/role-management.ts +0 -134
  95. package/client/pages/user/user-management.ts +0 -224
  96. package/client/route.ts +0 -67
  97. package/client/themes/auth-theme.css +0 -65
  98. package/client/utils/password-rule.ts +0 -37
  99. package/server/index.ts +0 -0
@@ -1,117 +0,0 @@
1
- import '@operato/i18n/ox-i18n.js'
2
-
3
- import { css, html, LitElement } from 'lit'
4
- import { customElement } from 'lit/decorators.js'
5
-
6
- import { i18next, localize } from '@operato/i18n'
7
- import { notify } from '@operato/layout'
8
- import { auth } from '@things-factory/auth-base/dist-client/auth.js'
9
-
10
- @customElement('delete-user-popup')
11
- export class DeleteUserPopup extends localize(i18next)(LitElement) {
12
- static styles = [
13
- css`
14
- :host {
15
- display: flex;
16
- flex-direction: column;
17
- color: var(--popup-content-color);
18
- background-color: var(--popup-content-background-color);
19
- padding: var(--popup-content-padding);
20
- }
21
-
22
- * {
23
- box-sizing: border-box;
24
- }
25
- *:focus {
26
- outline: none;
27
- }
28
-
29
- label {
30
- font: bold 14px var(--theme-font);
31
- color: var(--md-sys-color-primary);
32
- }
33
-
34
- input {
35
- border: var(--change-password-field-border);
36
- border-radius: var(--change-password-field-border-radius);
37
- padding: var(--change-password-field-padding);
38
-
39
- font: var(--change-password-field-font);
40
- width: var(--change-password-field-width);
41
- }
42
- input:focus {
43
- border: 1px solid var(--focus-background-color);
44
- }
45
-
46
- div.field {
47
- padding-bottom: 10px;
48
- }
49
-
50
- ::placeholder {
51
- font-size: 0.8rem;
52
- text-transform: capitalize;
53
- }
54
-
55
- button {
56
- background-color: var(--status-danger-color, #d14946);
57
- margin: 2px 2px 10px 2px;
58
- height: var(--button-height, 28px);
59
- color: var(--button-color, #fff);
60
- font: var(--button-font);
61
- border-radius: var(--button-radius, 5px);
62
- border: var(--button-border, 1px solid transparent);
63
- line-height: 1.5;
64
- }
65
- button:hover,
66
- button:active {
67
- background-color: var(--button-active-background-color, #22a6a7);
68
- border: var(--button-active-border);
69
- }
70
- `
71
- ]
72
-
73
- render() {
74
- return html`
75
- <h1><ox-i18n msgid="label.delete account"></ox-i18n></h1>
76
- <span><ox-i18n msgid="text.delete account warning message"></ox-i18n></span>
77
- <form @submit=${e => this.submit(e)}>
78
- <div class="field">
79
- <label for="email"><ox-i18n msgid="label.email"></ox-i18n></label>
80
- <input id="email" type="email" name="email" autocapitalize="off" required />
81
- <label for="password"><ox-i18n msgid="label.password"></ox-i18n></label>
82
- <input id="password" type="password" name="password" required />
83
- </div>
84
-
85
- <button class="ui button" type="submit"><ox-i18n msgid="label.delete account"></ox-i18n></button>
86
- </form>
87
- `
88
- }
89
-
90
- async submit(e: Event) {
91
- e.preventDefault()
92
-
93
- const form = e.target as HTMLFormElement
94
-
95
- var params = {}
96
- new FormData(form).forEach((value, key) => {
97
- params[key] = value
98
- })
99
-
100
- try {
101
- const message = await auth.deleteUser(params)
102
- notify({
103
- level: 'info',
104
- message
105
- })
106
-
107
- auth.signout()
108
- } catch (e: any) {
109
- form.reset()
110
-
111
- notify({
112
- level: 'error',
113
- message: 'message' in e ? e.message : e
114
- })
115
- }
116
- }
117
- }
@@ -1,127 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
-
3
- import { css, html, LitElement, nothing } from 'lit'
4
- import { customElement, property } from 'lit/decorators.js'
5
- import { connect } from 'pwa-helpers/connect-mixin'
6
-
7
- import { store } from '@operato/shell'
8
- import { ScrollbarStyles } from '@operato/styles'
9
-
10
- @customElement('domain-switch')
11
- export class DomainSwitch extends connect(store)(LitElement) {
12
- static styles = [
13
- ScrollbarStyles,
14
- css`
15
- :host {
16
- display: flex;
17
- max-width: 100%;
18
- background-color: var(--md-sys-color-primary-container, rgb(215 231 241));
19
- border-bottom: var(--border-dim-color);
20
- }
21
-
22
- :host * {
23
- vertical-align: middle;
24
- }
25
-
26
- div {
27
- flex: 1;
28
- display: flex;
29
- flex-direction: row;
30
- padding: var(--spacing-small);
31
- }
32
-
33
- md-icon {
34
- background-color: var(--md-sys-color-primary, rgb(46 121 190));
35
- margin-right: var(--spacing-small);
36
- padding: 2px;
37
- border-radius: 50%;
38
- font-size: var(--fontsize-large);
39
- color: var(--md-sys-color-on-primary, rgba(255,255,255,.9));
40
- }
41
- span,
42
- select {
43
- flex: 1;
44
- color: var(--md-sys-color-on-primary-container, rgb(50 66 82));
45
- font: bold 14px/20px var(--theme-font);
46
- }
47
-
48
- select {
49
- border: none;
50
- background-color: transparent;
51
- }
52
-
53
- select:focus {
54
- outline: 0;
55
- }
56
- :host([dark]) {
57
- background-color: rgba(0, 0, 0, 0.2);
58
- padding: 0 !important;
59
- border-bottom: none;
60
- }
61
- :host([dark]) md-icon {
62
- background-color: var(--secondary-text-color);
63
- margin: 1px 4px 0px 0px;
64
- padding: 1px 2px;
65
- border-radius: 50%;
66
- line-height: 19px;
67
- }
68
- :host([dark]) span,
69
- :host([dark]) select {
70
- color: var(--md-sys-color-on-primary);
71
- font: bold 13px/13px var(--theme-font);
72
- }
73
- :host([dark]) option {
74
- background-color: var(--primary-color, #585858);
75
- color: var(--md-sys-color-on-primary, #fff);
76
- }
77
- :host([dark]) span {
78
- line-height: 23px;
79
- }
80
-
81
- :host([rounded-corner]) {
82
- height: 30px;
83
- border-radius: 20px;
84
- border: var(--border-dim-color);
85
- }
86
- :host([rounded-corner]) div {
87
- padding: var(--spacing-small) var(--spacing-medium);
88
- }
89
- `
90
- ]
91
-
92
- @property({ type: Array }) domains: any[] = []
93
- @property({ type: Object }) domain: any
94
- @property({ type: String, attribute: true }) attrname: string = 'name'
95
- @property({ type: String, attribute: true }) icon?: string
96
-
97
- render() {
98
- const domains = this.domains || []
99
- const domain = this.domain || {}
100
- const attrname = this.attrname || 'name'
101
-
102
- return html`
103
- <div>
104
- ${this.icon ? html`<md-icon>${this.icon}</md-icon>` : nothing}
105
- ${domains.length <= 1
106
- ? html` <span>${domains[0]?.[attrname] || domain.name}</span> `
107
- : html`
108
- <select
109
- .value=${domain.subdomain}
110
- @change=${e => (window.location.pathname = `/auth/checkin/${e.target.value}`)}
111
- >
112
- ${domains.map(
113
- d => html`
114
- <option .value=${d.subdomain} ?selected=${d.subdomain == domain.subdomain}>${d[attrname]}</option>
115
- `
116
- )}
117
- </select>
118
- `}
119
- </div>
120
- `
121
- }
122
-
123
- stateChanged(state) {
124
- this.domains = state.app.domains
125
- this.domain = state.app.domain
126
- }
127
- }
@@ -1,104 +0,0 @@
1
- import gql from 'graphql-tag'
2
- import { css, html, LitElement } from 'lit'
3
- import { customElement, property, query } from 'lit/decorators.js'
4
-
5
- import { client, gqlContext } from '@operato/graphql'
6
- import { i18next, localize } from '@operato/i18n'
7
- import { OxPrompt } from '@operato/popup/ox-prompt.js'
8
-
9
- @customElement('invite-customer')
10
- class InviteCustomer extends localize(i18next)(LitElement) {
11
- static styles = [
12
- css`
13
- input {
14
- border: var(--border-dim-color);
15
- border-radius: var(--border-radius);
16
- margin: var(--input-margin);
17
- padding: var(--input-padding);
18
- min-width: 250px;
19
- font: var(--input-font);
20
- }
21
- md-outlined-button {
22
- margin: var(--input-margin);
23
- }
24
- @media screen and (max-width: 480px) {
25
- div {
26
- display: grid;
27
- }
28
- }
29
- `
30
- ]
31
-
32
- @property({ type: Array }) customers: any[] = []
33
-
34
- @query('input#customer-name') customerNameInput!: HTMLInputElement
35
-
36
- render() {
37
- return html`
38
- <div>
39
- <input id="customer-name" required />
40
- <md-outlined-button @click=${this.invite.bind(this)}>
41
- <md-icon slot="icon">group_add</md-icon>
42
- ${String(i18next.t('label.invite customer'))}
43
- </md-outlined-button>
44
- </div>
45
- `
46
- }
47
-
48
- async invite() {
49
- try {
50
- if (!this.customerNameInput.value)
51
- throw new Error(i18next.t('error.value is empty', { value: i18next.t('field.name') }))
52
-
53
- if (this.customers.find(c => c.name?.toLowerCase() === this.customerNameInput.value.toLowerCase())) {
54
- throw new Error(
55
- i18next.t('error.x already exists in y', { x: this.customerNameInput.value, y: i18next.t('field.customer') })
56
- )
57
- }
58
-
59
- if (
60
- await OxPrompt.open({
61
- title: i18next.t('text.are_you_sure'),
62
- text: i18next.t('text.do_you_want_to_invite_x', { x: i18next.t(`label.partner`) }),
63
- confirmButton: { text: i18next.t('button.confirm') },
64
- cancelButton: { text: i18next.t('button.cancel') }
65
- })
66
- ) {
67
- const customerDomainName = this.customerNameInput.value
68
-
69
- const response = await client.mutate({
70
- mutation: gql`
71
- mutation inviteCustomer($customerDomainName: String!) {
72
- inviteCustomer(customerDomainName: $customerDomainName)
73
- }
74
- `,
75
- variables: { customerDomainName },
76
- context: gqlContext()
77
- })
78
-
79
- if (!response.errors) {
80
- const answer = this.dispatchEvent(new CustomEvent('invitationCompleted'))
81
-
82
- if (answer) {
83
- await OxPrompt.open({
84
- type: 'success',
85
- title: i18next.t('text.completed'),
86
- confirmButton: { text: i18next.t('button.confirm') }
87
- })
88
- }
89
-
90
- this.customerNameInput.value = ''
91
- }
92
- }
93
- } catch (e: any) {
94
- document.dispatchEvent(
95
- new CustomEvent('notify', {
96
- detail: {
97
- level: 'error',
98
- message: 'message' in e ? e.message : e
99
- }
100
- })
101
- )
102
- }
103
- }
104
- }
@@ -1,96 +0,0 @@
1
- import './user-role-editor'
2
-
3
- import gql from 'graphql-tag'
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, query } from 'lit/decorators.js'
6
-
7
- import { client, gqlContext } from '@operato/graphql'
8
- import { i18next, localize } from '@operato/i18n'
9
- import { OxPrompt } from '@operato/popup/ox-prompt.js'
10
-
11
- @customElement('invite-user')
12
- class InviteUser extends localize(i18next)(LitElement) {
13
- static styles = css`
14
- :host {
15
- display: grid;
16
- }
17
-
18
- input {
19
- flex: 1;
20
-
21
- border: var(--border-dim-color);
22
- border-radius: var(--border-radius);
23
- margin: var(--input-margin);
24
- padding: var(--input-padding);
25
- min-width: 250px;
26
- font: var(--input-font);
27
- }
28
-
29
- md-outlined-button {
30
- margin: var(--input-margin);
31
- text-transform: capitalize;
32
- }
33
- `
34
-
35
- @query('input[name=email]') emailInput!: HTMLInputElement
36
-
37
- render() {
38
- return html`
39
- <input name="email" type="email" required name="invite-email" autocapitalize="off" />
40
- <md-outlined-button @click=${this.invite.bind(this)}>
41
- <md-icon slot="icon">group_add</md-icon>${String(i18next.t('label.invite user'))}
42
- </md-outlined-button>
43
- `
44
- }
45
-
46
- async invite() {
47
- try {
48
- if (!this.emailInput.checkValidity()) {
49
- throw new Error(i18next.t('error.not valid pattern of type', { type: 'e-mail' }))
50
- }
51
-
52
- if (
53
- await OxPrompt.open({
54
- title: i18next.t('text.are_you_sure'),
55
- text: i18next.t('text.do_you_want_to_invite_x', { x: i18next.t(`label.user`) }),
56
- confirmButton: { text: i18next.t('button.confirm') },
57
- cancelButton: { text: i18next.t('button.cancel') }
58
- })
59
- ) {
60
- await this.inviteUser(this.emailInput.value)
61
-
62
- this.dispatchEvent(new CustomEvent('invitationCompleted'))
63
- }
64
- } catch (e: any) {
65
- document.dispatchEvent(
66
- new CustomEvent('notify', {
67
- detail: {
68
- level: 'error',
69
- message: 'message' in e ? e.message : e
70
- }
71
- })
72
- )
73
- }
74
- }
75
-
76
- async inviteUser(email) {
77
- const response = await client.mutate({
78
- mutation: gql`
79
- mutation inviteUser($email: EmailAddress!) {
80
- inviteUser(email: $email)
81
- }
82
- `,
83
- variables: { email },
84
- context: gqlContext()
85
- })
86
-
87
- if (!response.errors) {
88
- await OxPrompt.open({
89
- title: i18next.t('text.completed'),
90
- confirmButton: { text: i18next.t('button.confirm') }
91
- })
92
-
93
- this.emailInput.value = ''
94
- }
95
- }
96
- }
@@ -1,101 +0,0 @@
1
- import '@operato/data-grist'
2
-
3
- import gql from 'graphql-tag'
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, property } from 'lit/decorators.js'
6
-
7
- import { client } from '@operato/graphql'
8
- import { i18next } from '@operato/i18n'
9
- import { isMobileDevice } from '@operato/utils'
10
-
11
- @customElement('my-login-history')
12
- class MyLoginHistory extends LitElement {
13
- static styles = css`
14
- :host {
15
- display: flex;
16
- flex-direction: column;
17
- background-color: var(--md-sys-color-background);
18
- padding: var(--spacing-large);
19
- overflow: auto;
20
- }
21
- ox-grist {
22
- flex: 1;
23
- }
24
- `
25
-
26
- @property({ type: Array }) histories: any[] = []
27
- @property({ type: Number }) limit?: number
28
-
29
- render() {
30
- if (!this.histories?.length) return html``
31
-
32
- const config = {
33
- rows: { appendable: false },
34
- pagination: { infinite: true },
35
- columns: [
36
- { type: 'gutter', gutterName: 'sequence' },
37
- {
38
- type: 'object',
39
- name: 'accessDomain',
40
- header: i18next.t('field.domain'),
41
- record: { editable: false },
42
- width: 200
43
- },
44
- {
45
- type: 'datetime',
46
- name: 'accessedAt',
47
- header: i18next.t('field.accessed-at'),
48
- record: { editable: false },
49
- width: 200
50
- },
51
- {
52
- type: 'string',
53
- name: 'accessorIp',
54
- header: i18next.t('field.ip_address'),
55
- record: { editable: false },
56
- width: 200
57
- }
58
- ]
59
- }
60
-
61
- return html`
62
- <ox-grist
63
- .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
64
- .config=${config}
65
- .data="${{ records: this.histories }}"
66
- ></ox-grist>
67
- `
68
- }
69
-
70
- firstUpdated() {
71
- this.fetchLoginHistories()
72
- }
73
-
74
- async fetchLoginHistories() {
75
- try {
76
- const response = await client.query({
77
- query: gql`
78
- query myLoginHistories($limit: Float!) {
79
- myLoginHistories(limit: $limit) {
80
- accessDomain {
81
- name
82
- }
83
- accessorIp
84
- accessedAt
85
- }
86
- }
87
- `,
88
- variables: { limit: this.limit || 10 }
89
- })
90
-
91
- if (response.errors?.length) return
92
- this.histories = response.data.myLoginHistories
93
- } catch (e: any) {
94
- this.showToast('message' in e ? e.message : e)
95
- }
96
- }
97
-
98
- showToast(message) {
99
- document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))
100
- }
101
- }
@@ -1,110 +0,0 @@
1
- import '@material/web/button/elevated-button.js'
2
-
3
- import gql from 'graphql-tag'
4
- import { css, html, LitElement } from 'lit'
5
- import { customElement, property, query } from 'lit/decorators.js'
6
-
7
- import { client, gqlContext } from '@operato/graphql'
8
- import { i18next, localize } from '@operato/i18n'
9
- import { OxPrompt } from '@operato/popup/ox-prompt.js'
10
-
11
- @customElement('ownership-transfer-popup')
12
- class OwnershipTransferPopup extends localize(i18next)(LitElement) {
13
- static styles = [
14
- css`
15
- :host {
16
- display: flex;
17
- flex-direction: column;
18
- background-color: var(--md-sys-color-background);
19
- padding: var(--spacing-large);
20
- overflow: auto;
21
- }
22
- .container {
23
- display: flex;
24
- flex-direction: column;
25
- flex: 1;
26
- }
27
- input {
28
- border: var(--border-dim-color);
29
- border-radius: var(--border-radius);
30
- margin: var(--input-margin);
31
- padding: var(--input-padding);
32
- min-width: 250px;
33
- font: var(--input-font);
34
- }
35
- .input-container {
36
- margin: auto;
37
- display: flex;
38
- }
39
- .input-container md-elevated-button {
40
- margin: auto 0px auto var(--spacing-large);
41
- }
42
- `
43
- ]
44
-
45
- @property({ type: Object }) user: any
46
-
47
- @query('input[name=email]') emailInput!: HTMLInputElement
48
-
49
- render() {
50
- return html`
51
- <div class="container">
52
- <div>${i18next.t('text.please enter the email of the user you want to transfer owner')}</div>
53
- <div class="input-container">
54
- <input name="email" />
55
- <md-elevated-button @click=${this.transferOwnership}>${i18next.t('button.confirm')}</md-elevated-button>
56
- </div>
57
- </div>
58
- `
59
- }
60
-
61
- async transferOwnership() {
62
- if (!this.doubleCheckEmail()) {
63
- this.showToast(i18next.t('text.email is not matched'))
64
-
65
- return
66
- }
67
-
68
- if (
69
- await OxPrompt.open({
70
- title: i18next.t('text.are_you_sure'),
71
- text: i18next.t('text.are_you_sure_to_transfer_owner'),
72
- confirmButton: { text: i18next.t('button.confirm') },
73
- cancelButton: { text: i18next.t('button.cancel') }
74
- })
75
- ) {
76
- const response = await client.mutate({
77
- mutation: gql`
78
- mutation transferOwner($email: EmailAddress!) {
79
- transferOwner(email: $email)
80
- }
81
- `,
82
- variables: { email: this.user.email },
83
- context: gqlContext()
84
- })
85
-
86
- if (!response.errors?.length) {
87
- await OxPrompt.open({
88
- type: 'success',
89
- title: i18next.t('text.completed'),
90
- text: i18next.t('text.owner_transfer_completed'),
91
- confirmButton: { text: i18next.t('button.confirm') }
92
- })
93
-
94
- history.back()
95
-
96
- this.dispatchEvent(new CustomEvent('ownershipTransferred', { bubbles: true, composed: true }))
97
- }
98
- } else {
99
- history.back()
100
- }
101
- }
102
-
103
- doubleCheckEmail() {
104
- return this.emailInput.value === this.user.email
105
- }
106
-
107
- showToast(message) {
108
- document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
109
- }
110
- }