@things-factory/auth-ui 10.1.17 → 10.1.18

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 (62) hide show
  1. package/dist-client/components/app-binding-detail.d.ts +46 -0
  2. package/dist-client/components/app-binding-detail.js +384 -0
  3. package/dist-client/components/app-binding-detail.js.map +1 -0
  4. package/dist-client/components/appliance-editor.d.ts +37 -0
  5. package/dist-client/components/appliance-editor.js +489 -0
  6. package/dist-client/components/appliance-editor.js.map +1 -0
  7. package/dist-client/components/application-editor.d.ts +31 -0
  8. package/dist-client/components/application-editor.js +491 -0
  9. package/dist-client/components/application-editor.js.map +1 -0
  10. package/dist-client/components/profile-component.js +28 -11
  11. package/dist-client/components/profile-component.js.map +1 -1
  12. package/dist-client/constants/application-type-parity.test.js +62 -0
  13. package/dist-client/constants/application-type-parity.test.js.map +1 -0
  14. package/dist-client/constants/application.d.ts +17 -7
  15. package/dist-client/constants/application.js +18 -8
  16. package/dist-client/constants/application.js.map +1 -1
  17. package/dist-client/pages/app-binding/app-bindings.d.ts +2 -0
  18. package/dist-client/pages/app-binding/app-bindings.js +19 -1
  19. package/dist-client/pages/app-binding/app-bindings.js.map +1 -1
  20. package/dist-client/pages/appliance/home.d.ts +2 -0
  21. package/dist-client/pages/appliance/home.js +21 -3
  22. package/dist-client/pages/appliance/home.js.map +1 -1
  23. package/dist-client/pages/application/applications.d.ts +2 -0
  24. package/dist-client/pages/application/applications.js +21 -3
  25. package/dist-client/pages/application/applications.js.map +1 -1
  26. package/dist-client/pages/secrets-are-not-printed.test.js +21 -3
  27. package/dist-client/pages/secrets-are-not-printed.test.js.map +1 -1
  28. package/dist-client/route.js +0 -15
  29. package/dist-client/route.js.map +1 -1
  30. package/dist-client/tsconfig.tsbuildinfo +1 -1
  31. package/dist-client/utils/form-values.d.ts +29 -0
  32. package/dist-client/utils/form-values.js +45 -0
  33. package/dist-client/utils/form-values.js.map +1 -1
  34. package/dist-client/utils/form-values.test.js +59 -1
  35. package/dist-client/utils/form-values.test.js.map +1 -1
  36. package/dist-client/utils/webauthn-verification.d.ts +56 -0
  37. package/dist-client/utils/webauthn-verification.js +79 -0
  38. package/dist-client/utils/webauthn-verification.js.map +1 -0
  39. package/dist-client/utils/webauthn-verification.test.js +79 -0
  40. package/dist-client/utils/webauthn-verification.test.js.map +1 -0
  41. package/package.json +3 -3
  42. package/things-factory.config.js +0 -5
  43. package/translations/en.json +25 -0
  44. package/translations/ja.json +26 -0
  45. package/translations/ko.json +25 -0
  46. package/translations/ms.json +26 -0
  47. package/translations/zh.json +26 -0
  48. package/dist-client/pages/app-binding/app-binding.d.ts +0 -2
  49. package/dist-client/pages/app-binding/app-binding.js +0 -371
  50. package/dist-client/pages/app-binding/app-binding.js.map +0 -1
  51. package/dist-client/pages/appliance/appliance.d.ts +0 -2
  52. package/dist-client/pages/appliance/appliance.js +0 -390
  53. package/dist-client/pages/appliance/appliance.js.map +0 -1
  54. package/dist-client/pages/appliance/register.js +0 -166
  55. package/dist-client/pages/appliance/register.js.map +0 -1
  56. package/dist-client/pages/application/application.d.ts +0 -2
  57. package/dist-client/pages/application/application.js +0 -384
  58. package/dist-client/pages/application/application.js.map +0 -1
  59. package/dist-client/pages/application/register.js +0 -246
  60. package/dist-client/pages/application/register.js.map +0 -1
  61. /package/dist-client/{pages/appliance/register.d.ts → constants/application-type-parity.test.d.ts} +0 -0
  62. /package/dist-client/{pages/application/register.d.ts → utils/webauthn-verification.test.d.ts} +0 -0
@@ -1,371 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import '@material/web/icon/icon.js';
3
- import Clipboard from 'clipboard';
4
- import gql from 'graphql-tag';
5
- import { css, html } from 'lit';
6
- import { customElement, property, state } from 'lit/decorators.js';
7
- import { asyncReplace } from 'lit/directives/async-replace.js';
8
- import { client } from '@operato/graphql';
9
- import { i18next } from '@operato/i18n';
10
- import { navigate, PageView } from '@operato/shell';
11
- import '../../components/secret-field.js';
12
- import { parseJwt, sleep } from '@operato/utils';
13
- let AppBinding = class AppBinding extends PageView {
14
- static { this.styles = [
15
- css `
16
- :host { display: flex;
17
- flex-direction: column;
18
- overflow-y: auto;
19
-
20
- position: relative;
21
-
22
- background-color: var(--md-sys-color-background);
23
- padding: var(--spacing-large);
24
- }
25
-
26
- h2 { margin: var(--title-margin);
27
- font: var(--title-font);
28
- color: var(--title-text-color);
29
- }
30
-
31
- [page-description] { margin: var(--page-description-margin);
32
- font: var(--page-description-font);
33
- color: var(--page-description-color);
34
- }
35
-
36
- [icon] { position: absolute;
37
- top: 10px;
38
- right: 10px;
39
-
40
- max-width: 80px;
41
- }
42
-
43
- [icon] img { max-width: 100%;
44
- max-height: 100%;
45
- }
46
-
47
- [fieldset-container] { background-color: var(--md-sys-color-surface);
48
- margin: var(--spacing-large) 0 var(--spacing-medium) 0;
49
- padding: var(--spacing-medium);
50
- border-radius: var(--border-radius);
51
- box-shadow: var(--box-shadow);
52
-
53
- label { font: var(--label-font);
54
- color: var(--label-color, var(--md-sys-color-on-surface));
55
- text-transform: var(--label-text-transform);
56
- }
57
- input {
58
- background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));
59
- color: var(--input-field-color, var(--md-sys-color-on-surface));
60
- border: var(--border-dim-color);
61
- border-radius: var(--border-radius);
62
- margin: var(--input-margin);
63
- padding: var(--input-padding);
64
- font: var(--input-font);
65
-
66
- flex: 1;
67
- }
68
- select:focus,
69
- input:focus,
70
- button { outline: none;
71
- }
72
- form { max-width: var(--content-container-max-width);
73
- }
74
- }
75
-
76
- [fieldset-container] fieldset { margin: 0;
77
- margin-top: -15px;
78
- }
79
-
80
- fieldset { border-radius: var(--border-radius);
81
- border: var(--border-dim-color);
82
- margin: var(--fieldset-margin);
83
- padding: var(--fieldset-padding);
84
- }
85
-
86
- legend { padding: var(--legend-padding);
87
- font-weight: bold;
88
- color: var(--legend-color);
89
- }
90
-
91
- [field-2column] { display: grid;
92
- grid-template-columns: 1fr 1fr;
93
- grid-gap: 15px;
94
- }
95
-
96
- [field] { display: flex;
97
- flex-direction: column;
98
- position: relative;
99
- }
100
-
101
- [grid-span] { grid-column: span 2;
102
- }
103
-
104
- button,
105
- [button-in-field] { background-color: var(--button-background-color);
106
- border: var(--button-border);
107
- border-radius: var(--button-border-radius);
108
- padding: var(--button-padding);
109
- color: var(--button-color);
110
- font: var(--button-font);
111
- text-transform: var(--button-text-transform);
112
-
113
- margin: var(--spacing-medium) 0 var(--spacing-medium) var(--spacing-medium);
114
- float: right;
115
- text-decoration: none;
116
- }
117
-
118
- button:hover { border: var(--button-activ-border);
119
- box-shadow: var(--button-active-box-shadow);
120
- }
121
-
122
- [button-in-field] { border-radius: 0 var(--button-border-radius) var(--button-border-radius) 0;
123
- position: absolute;
124
- top: 12px;
125
- right: 0;
126
- max-height: 36px;
127
- }
128
-
129
- [input-hint] { font: var(--input-hint-font);
130
- color: var(--input-hint-color);
131
- }
132
-
133
- @media screen and (max-width: 480px) { [field] { grid-column: span 2;
134
- }
135
- }
136
- `
137
- ]; }
138
- get context() {
139
- return { title: { icon: 'link',
140
- text: this.appbinding.name
141
- }
142
- };
143
- }
144
- render() {
145
- var binding = this.appbinding || {};
146
- var app = this.appbinding?.application || {};
147
- var refreshTokenExp = this._refreshTokenInfo?.exp;
148
- var accessTokenExp = this._accessTokenInfo?.exp;
149
- return html `
150
- <div>
151
- <h2><md-icon>link</md-icon>&nbsp;${app.name}</h2>
152
- <p page-description>${app.description}</p>
153
- </div>
154
-
155
- ${app.icon
156
- ? html `
157
- <div icon>
158
- <img src=${app.icon} />
159
- </div>
160
- `
161
- : html ``}
162
-
163
- <form>
164
- <div fieldset-container>
165
- <fieldset>
166
- <legend>application</legend>
167
- <div field-2column>
168
- <div field grid-span>
169
- <label for="app-name">app name</label>
170
- <input id="app-name" type="text" .value=${app.name} readonly />
171
- </div>
172
-
173
- <div field grid-span>
174
- <label for="app-description">description</label>
175
- <input id="app-description" type="text" .value=${app.description} readonly />
176
- </div>
177
-
178
- <div field>
179
- <label for="contact-email">contact email</label>
180
- <input id="contact-email" type="text" .value=${app.email} readonly />
181
- </div>
182
- </div>
183
- </fieldset>
184
- </div>
185
-
186
- <div fieldset-container>
187
- <fieldset>
188
- <legend>binding</legend>
189
- <div field-2column>
190
- <div field grid-span>
191
- <label for="id">id</label>
192
- <input id="id" type="text" .value=${binding.id} readonly />
193
- </div>
194
-
195
- <div field grid-span>
196
- <label for="name">name</label>
197
- <input id="name" type="text" .value=${binding.email} readonly />
198
- </div>
199
-
200
- <div field>
201
- <label for="status">status</label>
202
- <input id="status" type="text" .value=${binding.status} readonly />
203
- </div>
204
-
205
- <div field>
206
- <label for="scope">scope</label>
207
- <input id="scope" type="text" .value=${binding.scope} readonly />
208
- </div>
209
- </div>
210
- </fieldset>
211
- </div>
212
-
213
- <div fieldset-container>
214
- <fieldset>
215
- <legend>binding credential</legend>
216
- <div field-2column>
217
- <div field grid-span>
218
- <label for="access-token">${i18next.t('label.access token')}</label>
219
- <secret-field id="access-token" .value=${this.accessToken || ''}></secret-field>
220
- ${accessTokenExp
221
- ? html `<div input-hint>
222
- ${i18next.t('text.expires at x', { x: new Date(accessTokenExp).toLocaleString() })} ·
223
- ${asyncReplace(this.expTimer(accessTokenExp))}
224
- </div>`
225
- : html ``}
226
- </div>
227
-
228
- <div field grid-span>
229
- <label for="refresh-token">${i18next.t('label.refresh token')}</label>
230
- <secret-field id="refresh-token" .value=${binding.refreshToken || ''}></secret-field>
231
- ${refreshTokenExp
232
- ? html `<div input-hint>
233
- ${i18next.t('text.expires at x', { x: new Date(refreshTokenExp).toLocaleString() })} ·
234
- ${asyncReplace(this.expTimer(refreshTokenExp))}
235
- </div>`
236
- : html ``}
237
- </div>
238
- </div>
239
- </fieldset>
240
- </div>
241
-
242
- <button @click=${this.deleteAppBinding.bind(this)}>delete this application binding</button>
243
- <button @click=${this.renewApplicationAccessToken.bind(this)}>renew access token</button>
244
- </form>
245
- `;
246
- }
247
- async *expTimer(exp) {
248
- const DAY = 24 * 60 * 60;
249
- const HOUR = 60 * 60;
250
- const MIN = 60;
251
- while (this.active) {
252
- var remain = Math.floor(Number(exp) - Date.now() / 1000);
253
- const days = Math.floor(remain / DAY);
254
- remain -= days * DAY;
255
- const hours = Math.floor(remain / HOUR);
256
- remain -= hours * HOUR;
257
- const mins = Math.floor(remain / MIN);
258
- const secs = remain - mins * MIN;
259
- yield `${days} days ${hours} hours ${mins} mins ${secs} seconds remain`;
260
- await sleep(1000);
261
- }
262
- }
263
- firstUpdated() {
264
- const copybuttons = this.renderRoot.querySelectorAll('[clipboard-copy]');
265
- this.clipboard = new Clipboard(copybuttons, { target: (trigger => trigger.parentElement.querySelector('input'))
266
- });
267
- }
268
- updated(changes) {
269
- if (changes.has('appbinding')) {
270
- const { refreshToken } = this.appbinding || {};
271
- this._refreshTokenInfo = refreshToken ? parseJwt(refreshToken) : {};
272
- }
273
- if (changes.has('accessToken')) {
274
- this._accessTokenInfo = this.accessToken ? parseJwt(this.accessToken) : {};
275
- }
276
- }
277
- async pageUpdated(changes, lifecycle, before) {
278
- if (this.active) { /*
279
- * this page is activated
280
- */
281
- await this.fetchAppBinding();
282
- }
283
- else { /* this page is deactivated */
284
- }
285
- }
286
- async fetchAppBinding() {
287
- const response = await client.query({ query: gql `
288
- query ($id: String!) { appBinding(id: $id) { id
289
- name
290
- description
291
- email
292
- scope
293
- status
294
- application { id
295
- name
296
- description
297
- email
298
- icon
299
- }
300
- refreshToken
301
- }
302
- }
303
- `,
304
- variables: { id: this.lifecycle.resourceId
305
- }
306
- });
307
- this.appbinding = response.data.appBinding;
308
- }
309
- async deleteAppBinding(e) {
310
- e.preventDefault();
311
- const id = this.lifecycle.resourceId;
312
- const response = await client.mutate({ mutation: gql `
313
- mutation ($id: String!) { deleteAppBinding(id: $id)
314
- }
315
- `,
316
- variables: { id
317
- }
318
- });
319
- const result = response.data.deleteAppBinding;
320
- if (result) {
321
- console.log('delete sucess');
322
- navigate(`app-bindings`);
323
- }
324
- else {
325
- console.error('delete fail');
326
- }
327
- }
328
- async renewApplicationAccessToken(e) {
329
- e.preventDefault();
330
- const id = this.lifecycle.resourceId;
331
- const response = await client.mutate({ mutation: gql `
332
- mutation ($id: String!) { renewApplicationAccessToken(id: $id) { accessToken
333
- refreshToken
334
- }
335
- }
336
- `,
337
- variables: { id
338
- }
339
- });
340
- if (response.errors) {
341
- console.error('renew application access token fail');
342
- }
343
- else {
344
- const { accessToken, refreshToken } = response.data.renewApplicationAccessToken;
345
- this.accessToken = accessToken;
346
- this.appbinding = { ...this.appbinding,
347
- refreshToken
348
- };
349
- }
350
- }
351
- };
352
- __decorate([
353
- property({ type: Object }),
354
- __metadata("design:type", Object)
355
- ], AppBinding.prototype, "appbinding", void 0);
356
- __decorate([
357
- property({ type: String }),
358
- __metadata("design:type", String)
359
- ], AppBinding.prototype, "accessToken", void 0);
360
- __decorate([
361
- state(),
362
- __metadata("design:type", Object)
363
- ], AppBinding.prototype, "_refreshTokenInfo", void 0);
364
- __decorate([
365
- state(),
366
- __metadata("design:type", Object)
367
- ], AppBinding.prototype, "_accessTokenInfo", void 0);
368
- AppBinding = __decorate([
369
- customElement('app-binding-page')
370
- ], AppBinding);
371
- //# sourceMappingURL=app-binding.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-binding.js","sourceRoot":"","sources":["../../../client/pages/app-binding/app-binding.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport Clipboard from 'clipboard'\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { asyncReplace } from 'lit/directives/async-replace.js'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { navigate, PageView } from '@operato/shell'\n\nimport '../../components/secret-field.js'\nimport { parseJwt, sleep } from '@operato/utils'\n\n@customElement('app-binding-page')\nclass AppBinding extends PageView { static styles = [\n css`\n :host { display: flex;\n flex-direction: column;\n overflow-y: auto;\n\n position: relative;\n\n background-color: var(--md-sys-color-background);\n padding: var(--spacing-large);\n }\n\n h2 { margin: var(--title-margin);\n font: var(--title-font);\n color: var(--title-text-color);\n }\n\n [page-description] { margin: var(--page-description-margin);\n font: var(--page-description-font);\n color: var(--page-description-color);\n }\n\n [icon] { position: absolute;\n top: 10px;\n right: 10px;\n\n max-width: 80px;\n }\n\n [icon] img { max-width: 100%;\n max-height: 100%;\n }\n\n [fieldset-container] { background-color: var(--md-sys-color-surface);\n margin: var(--spacing-large) 0 var(--spacing-medium) 0;\n padding: var(--spacing-medium);\n border-radius: var(--border-radius);\n box-shadow: var(--box-shadow);\n\n label { font: var(--label-font);\n color: var(--label-color, var(--md-sys-color-on-surface));\n text-transform: var(--label-text-transform);\n }\n input {\n background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));\n color: var(--input-field-color, var(--md-sys-color-on-surface));\n border: var(--border-dim-color);\n border-radius: var(--border-radius);\n margin: var(--input-margin);\n padding: var(--input-padding);\n font: var(--input-font);\n\n flex: 1;\n }\n select:focus,\n input:focus,\n button { outline: none;\n }\n form { max-width: var(--content-container-max-width);\n }\n }\n\n [fieldset-container] fieldset { margin: 0;\n margin-top: -15px;\n }\n\n fieldset { border-radius: var(--border-radius);\n border: var(--border-dim-color);\n margin: var(--fieldset-margin);\n padding: var(--fieldset-padding);\n }\n\n legend { padding: var(--legend-padding);\n font-weight: bold;\n color: var(--legend-color);\n }\n\n [field-2column] { display: grid;\n grid-template-columns: 1fr 1fr;\n grid-gap: 15px;\n }\n\n [field] { display: flex;\n flex-direction: column;\n position: relative;\n }\n\n [grid-span] { grid-column: span 2;\n }\n\n button,\n [button-in-field] { background-color: var(--button-background-color);\n border: var(--button-border);\n border-radius: var(--button-border-radius);\n padding: var(--button-padding);\n color: var(--button-color);\n font: var(--button-font);\n text-transform: var(--button-text-transform);\n\n margin: var(--spacing-medium) 0 var(--spacing-medium) var(--spacing-medium);\n float: right;\n text-decoration: none;\n }\n\n button:hover { border: var(--button-activ-border);\n box-shadow: var(--button-active-box-shadow);\n }\n\n [button-in-field] { border-radius: 0 var(--button-border-radius) var(--button-border-radius) 0;\n position: absolute;\n top: 12px;\n right: 0;\n max-height: 36px;\n }\n\n [input-hint] { font: var(--input-hint-font);\n color: var(--input-hint-color);\n }\n\n @media screen and (max-width: 480px) { [field] { grid-column: span 2;\n }\n }\n `\n ]\n\n @property({ type: Object }) appbinding: any\n @property({ type: String }) accessToken?: string\n\n @state() _refreshTokenInfo: any\n @state() _accessTokenInfo: any\n\n private clipboard?: Clipboard\n\n get context() { return { title: { icon: 'link',\n text: this.appbinding.name\n }\n }\n }\n\n render() { var binding = this.appbinding || {}\n var app = this.appbinding?.application || {}\n var refreshTokenExp = this._refreshTokenInfo?.exp\n var accessTokenExp = this._accessTokenInfo?.exp\n\n return html`\n <div>\n <h2><md-icon>link</md-icon>&nbsp;${app.name}</h2>\n <p page-description>${app.description}</p>\n </div>\n\n ${app.icon\n ? html`\n <div icon>\n <img src=${app.icon} />\n </div>\n `\n : html``}\n\n <form>\n <div fieldset-container>\n <fieldset>\n <legend>application</legend>\n <div field-2column>\n <div field grid-span>\n <label for=\"app-name\">app name</label>\n <input id=\"app-name\" type=\"text\" .value=${app.name} readonly />\n </div>\n\n <div field grid-span>\n <label for=\"app-description\">description</label>\n <input id=\"app-description\" type=\"text\" .value=${app.description} readonly />\n </div>\n\n <div field>\n <label for=\"contact-email\">contact email</label>\n <input id=\"contact-email\" type=\"text\" .value=${app.email} readonly />\n </div>\n </div>\n </fieldset>\n </div>\n\n <div fieldset-container>\n <fieldset>\n <legend>binding</legend>\n <div field-2column>\n <div field grid-span>\n <label for=\"id\">id</label>\n <input id=\"id\" type=\"text\" .value=${binding.id} readonly />\n </div>\n\n <div field grid-span>\n <label for=\"name\">name</label>\n <input id=\"name\" type=\"text\" .value=${binding.email} readonly />\n </div>\n\n <div field>\n <label for=\"status\">status</label>\n <input id=\"status\" type=\"text\" .value=${binding.status} readonly />\n </div>\n\n <div field>\n <label for=\"scope\">scope</label>\n <input id=\"scope\" type=\"text\" .value=${binding.scope} readonly />\n </div>\n </div>\n </fieldset>\n </div>\n\n <div fieldset-container>\n <fieldset>\n <legend>binding credential</legend>\n <div field-2column>\n <div field grid-span>\n <label for=\"access-token\">${i18next.t('label.access token')}</label>\n <secret-field id=\"access-token\" .value=${this.accessToken || ''}></secret-field>\n ${accessTokenExp\n ? html`<div input-hint>\n ${i18next.t('text.expires at x', { x: new Date(accessTokenExp).toLocaleString() })} ·\n ${asyncReplace(this.expTimer(accessTokenExp))}\n </div>`\n : html``}\n </div>\n\n <div field grid-span>\n <label for=\"refresh-token\">${i18next.t('label.refresh token')}</label>\n <secret-field id=\"refresh-token\" .value=${binding.refreshToken || ''}></secret-field>\n ${refreshTokenExp\n ? html`<div input-hint>\n ${i18next.t('text.expires at x', { x: new Date(refreshTokenExp).toLocaleString() })} ·\n ${asyncReplace(this.expTimer(refreshTokenExp))}\n </div>`\n : html``}\n </div>\n </div>\n </fieldset>\n </div>\n\n <button @click=${this.deleteAppBinding.bind(this)}>delete this application binding</button>\n <button @click=${this.renewApplicationAccessToken.bind(this)}>renew access token</button>\n </form>\n `\n }\n\n async *expTimer(exp) { const DAY = 24 * 60 * 60\n const HOUR = 60 * 60\n const MIN = 60\n\n while (this.active) { var remain = Math.floor(Number(exp) - Date.now() / 1000)\n const days = Math.floor(remain / DAY)\n remain -= days * DAY\n const hours = Math.floor(remain / HOUR)\n remain -= hours * HOUR\n const mins = Math.floor(remain / MIN)\n const secs = remain - mins * MIN\n\n yield `${days} days ${hours} hours ${mins} mins ${secs} seconds remain`\n\n await sleep(1000)\n }\n }\n\n firstUpdated() { const copybuttons = this.renderRoot.querySelectorAll('[clipboard-copy]')\n\n this.clipboard = new Clipboard(copybuttons, { target: (trigger => trigger.parentElement.querySelector('input')) as any\n })\n }\n\n updated(changes) { /*\n * If this page properties are changed, this callback will be invoked.\n * This callback will be called back only when this page is activated.\n */\n if (changes.has('appbinding')) { const { refreshToken } = this.appbinding || {}\n this._refreshTokenInfo = refreshToken ? parseJwt(refreshToken) : {}\n }\n\n if (changes.has('accessToken')) { this._accessTokenInfo = this.accessToken ? parseJwt(this.accessToken) : {}\n }\n }\n\n async pageUpdated(changes, lifecycle, before) { if (this.active) { /*\n * this page is activated\n */\n await this.fetchAppBinding()\n } else { /* this page is deactivated */\n }\n }\n\n async fetchAppBinding() { const response = await client.query({ query: gql`\n query ($id: String!) { appBinding(id: $id) { id\n name\n description\n email\n scope\n status\n application { id\n name\n description\n email\n icon\n }\n refreshToken\n }\n }\n `,\n variables: { id: this.lifecycle.resourceId\n }\n })\n\n this.appbinding = response.data.appBinding\n }\n\n async deleteAppBinding(e) { e.preventDefault()\n\n const id = this.lifecycle.resourceId\n\n const response = await client.mutate({ mutation: gql`\n mutation ($id: String!) { deleteAppBinding(id: $id)\n }\n `,\n variables: { id\n }\n })\n\n const result = response.data.deleteAppBinding\n if (result) { console.log('delete sucess')\n navigate(`app-bindings`)\n } else { console.error('delete fail')\n }\n }\n\n async renewApplicationAccessToken(e) { e.preventDefault()\n\n const id = this.lifecycle.resourceId\n\n const response = await client.mutate({ mutation: gql`\n mutation ($id: String!) { renewApplicationAccessToken(id: $id) { accessToken\n refreshToken\n }\n }\n `,\n variables: { id\n }\n })\n\n if (response.errors) { console.error('renew application access token fail')\n } else { const { accessToken, refreshToken } = response.data.renewApplicationAccessToken\n this.accessToken = accessToken\n this.appbinding = { ...this.appbinding,\n refreshToken\n }\n }\n }\n}\n"]}
@@ -1,2 +0,0 @@
1
- import '@material/web/icon/icon.js';
2
- import '../../components/secret-field.js';