@openremote/manager 1.8.0-snapshot.20250725120002 → 1.8.0-snapshot.20250728102340

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.
@@ -43,105 +43,105 @@ let PageAccount = class PageAccount extends Page {
43
43
  this._passwordPolicy = [];
44
44
  }
45
45
  static _getStyle() {
46
- return css `
47
- #wrapper {
48
- height: 100%;
49
- width: 100%;
50
- display: flex;
51
- flex-direction: column;
52
- }
53
-
54
- #title {
55
- padding: 0 20px;
56
- font-size: 18px;
57
- font-weight: bold;
58
- width: calc(100% - 40px);
59
- max-width: 1360px;
60
- margin: 20px auto;
61
- align-items: center;
62
- display: flex;
63
- color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)});
64
- }
65
-
66
- #title or-icon {
67
- margin-right: 10px;
68
- margin-left: 14px;
69
- }
70
-
71
- .panel {
72
- flex: 0;
73
- width: 100%;
74
- box-sizing: border-box;
75
- max-width: 1360px;
76
- background-color: white;
77
- border: 1px solid #e5e5e5;
78
- border-radius: 5px;
79
- position: relative;
80
- margin: 0 auto 10px;
81
- padding: 12px 24px 24px;
82
- display: flex;
83
- flex-direction: column;
84
- }
85
-
86
- .panel-title {
87
- display: flex;
88
- text-transform: uppercase;
89
- font-weight: bolder;
90
- color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)});
91
- line-height: 1em;
92
- margin-bottom: 10px;
93
- margin-top: 0;
94
- flex: 0 0 auto;
95
- letter-spacing: 0.025em;
96
- align-items: center;
97
- min-height: 36px;
98
- }
99
-
100
- or-icon {
101
- vertical-align: middle;
102
- --or-icon-width: 20px;
103
- --or-icon-height: 20px;
104
- margin-right: 2px;
105
- margin-left: -5px;
106
- }
107
-
108
- .row {
109
- display: flex;
110
- flex-direction: row;
111
- flex: 1 1 0;
112
- gap: 24px;
113
- }
114
-
115
- .column {
116
- display: flex;
117
- flex-direction: column;
118
- margin: 0px;
119
- flex: 1 1 0;
120
- gap: 20px;
121
- }
122
-
123
- h5 {
124
- margin-bottom: 0;
125
- }
126
-
127
- @media screen and (max-width: 768px) {
128
- #title {
129
- padding: 0;
130
- width: 100%;
131
- }
132
-
133
- .row {
134
- display: block;
135
- flex-direction: column;
136
- gap: 0;
137
- }
138
-
139
- .panel {
140
- border-radius: 0;
141
- border-left: 0px;
142
- border-right: 0px;
143
- }
144
- }
46
+ return css `
47
+ #wrapper {
48
+ height: 100%;
49
+ width: 100%;
50
+ display: flex;
51
+ flex-direction: column;
52
+ }
53
+
54
+ #title {
55
+ padding: 0 20px;
56
+ font-size: 18px;
57
+ font-weight: bold;
58
+ width: calc(100% - 40px);
59
+ max-width: 1360px;
60
+ margin: 20px auto;
61
+ align-items: center;
62
+ display: flex;
63
+ color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)});
64
+ }
65
+
66
+ #title or-icon {
67
+ margin-right: 10px;
68
+ margin-left: 14px;
69
+ }
70
+
71
+ .panel {
72
+ flex: 0;
73
+ width: 100%;
74
+ box-sizing: border-box;
75
+ max-width: 1360px;
76
+ background-color: white;
77
+ border: 1px solid #e5e5e5;
78
+ border-radius: 5px;
79
+ position: relative;
80
+ margin: 0 auto 10px;
81
+ padding: 12px 24px 24px;
82
+ display: flex;
83
+ flex-direction: column;
84
+ }
85
+
86
+ .panel-title {
87
+ display: flex;
88
+ text-transform: uppercase;
89
+ font-weight: bolder;
90
+ color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)});
91
+ line-height: 1em;
92
+ margin-bottom: 10px;
93
+ margin-top: 0;
94
+ flex: 0 0 auto;
95
+ letter-spacing: 0.025em;
96
+ align-items: center;
97
+ min-height: 36px;
98
+ }
99
+
100
+ or-icon {
101
+ vertical-align: middle;
102
+ --or-icon-width: 20px;
103
+ --or-icon-height: 20px;
104
+ margin-right: 2px;
105
+ margin-left: -5px;
106
+ }
107
+
108
+ .row {
109
+ display: flex;
110
+ flex-direction: row;
111
+ flex: 1 1 0;
112
+ gap: 24px;
113
+ }
114
+
115
+ .column {
116
+ display: flex;
117
+ flex-direction: column;
118
+ margin: 0px;
119
+ flex: 1 1 0;
120
+ gap: 20px;
121
+ }
122
+
123
+ h5 {
124
+ margin-bottom: 0;
125
+ }
126
+
127
+ @media screen and (max-width: 768px) {
128
+ #title {
129
+ padding: 0;
130
+ width: 100%;
131
+ }
132
+
133
+ .row {
134
+ display: block;
135
+ flex-direction: column;
136
+ gap: 0;
137
+ }
138
+
139
+ .panel {
140
+ border-radius: 0;
141
+ border-left: 0px;
142
+ border-right: 0px;
143
+ }
144
+ }
145
145
  `;
146
146
  }
147
147
  static get styles() {
@@ -158,53 +158,53 @@ let PageAccount = class PageAccount extends Page {
158
158
  }
159
159
  render() {
160
160
  if (!manager.authenticated) {
161
- return html `
162
- <or-translate value="notAuthenticated"></or-translate>
161
+ return html `
162
+ <or-translate value="notAuthenticated"></or-translate>
163
163
  `;
164
164
  }
165
165
  if (!manager.isKeycloak()) {
166
- return html `
167
- <or-translate value="notSupported"></or-translate>
166
+ return html `
167
+ <or-translate value="notSupported"></or-translate>
168
168
  `;
169
169
  }
170
170
  const readonly = !manager.hasRole("write:user" /* ClientRole.WRITE_USER */);
171
- return html `
172
- <div id="wrapper">
173
- <div id="title">
174
- <or-icon icon="account"></or-icon>
175
- <or-translate value="account">
176
- </div>
177
- <div id="content" class="panel">
178
-
179
- <p class="panel-title">${i18next.t("user")} ${i18next.t("settings")}</p>
180
-
181
- <!-- Account settings row -->
171
+ return html `
172
+ <div id="wrapper">
173
+ <div id="title">
174
+ <or-icon icon="account"></or-icon>
175
+ <or-translate value="account">
176
+ </div>
177
+ <div id="content" class="panel">
178
+
179
+ <p class="panel-title">${i18next.t("user")} ${i18next.t("settings")}</p>
180
+
181
+ <!-- Account settings row -->
182
182
  ${guard([this._user], () => until(this._getAccountRowTemplate(this._user, readonly, (_user, dirty, invalid) => {
183
183
  this._dirty = dirty;
184
184
  this._invalid = invalid;
185
- })))}
186
-
187
- <!-- Actions row (such as the save button) -->
188
- ${when(this._user, () => until(this._getActionsRowTemplate(this._user)))}
189
-
190
- </div>
191
-
192
- ${when(manager.isKeycloak(), () => html `
193
- <div class="panel">
194
- <p class="panel-title">
195
- <or-translate value="twoFactorAuth"></or-translate>
196
- </p>
197
- <div class="row">
198
- <div class="column">
199
- <or-mwc-input .type="${InputType.BUTTON}" label="${i18next.t('twoFactorConfigure')}"
200
- outlined
201
- @or-mwc-input-changed="${() => manager.login({ action: "CONFIGURE_TOTP" })}"
202
- ></or-mwc-input>
203
- </div>
204
- </div>
205
- </div>
206
- `)}
207
- </div>
185
+ })))}
186
+
187
+ <!-- Actions row (such as the save button) -->
188
+ ${when(this._user, () => until(this._getActionsRowTemplate(this._user)))}
189
+
190
+ </div>
191
+
192
+ ${when(manager.isKeycloak(), () => html `
193
+ <div class="panel">
194
+ <p class="panel-title">
195
+ <or-translate value="twoFactorAuth"></or-translate>
196
+ </p>
197
+ <div class="row">
198
+ <div class="column">
199
+ <or-mwc-input .type="${InputType.BUTTON}" label="${i18next.t('twoFactorConfigure')}"
200
+ outlined
201
+ @or-mwc-input-changed="${() => manager.login({ action: "CONFIGURE_TOTP" })}"
202
+ ></or-mwc-input>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ `)}
207
+ </div>
208
208
  `;
209
209
  }
210
210
  /**
@@ -218,104 +218,104 @@ let PageAccount = class PageAccount extends Page {
218
218
  if (!user) {
219
219
  user = yield this._getUser();
220
220
  }
221
- return html `
222
- <div class="row">
223
- <div class="column">
224
- <!-- user details -->
225
- <h5>${i18next.t("details")}</h5>
226
- <or-mwc-input id="new-username" class="validate"
227
- .label="${i18next.t("username")}"
228
- .type="${InputType.TEXT}"
229
- ?required="${!registrationEmailAsUsername}"
230
- .disabled="${true}"
231
- minLength="3" maxLength="255" pattern="[A-Za-z0-9\\-_+@\\.ßçʊÇʊ]+"
232
- .validationMessage="${i18next.t("invalidUsername")}"
233
- .value="${user === null || user === void 0 ? void 0 : user.username}" autocomplete="false"
221
+ return html `
222
+ <div class="row">
223
+ <div class="column">
224
+ <!-- user details -->
225
+ <h5>${i18next.t("details")}</h5>
226
+ <or-mwc-input id="new-username" class="validate"
227
+ .label="${i18next.t("username")}"
228
+ .type="${InputType.TEXT}"
229
+ ?required="${!registrationEmailAsUsername}"
230
+ .disabled="${true}"
231
+ minLength="3" maxLength="255" pattern="[A-Za-z0-9\\-_+@\\.ßçʊÇʊ]+"
232
+ .validationMessage="${i18next.t("invalidUsername")}"
233
+ .value="${user === null || user === void 0 ? void 0 : user.username}" autocomplete="false"
234
234
  @or-mwc-input-changed="${(e) => {
235
235
  user.username = e.detail.value;
236
236
  onchange === null || onchange === void 0 ? void 0 : onchange(user, true, this._isInvalid());
237
- }}"
238
- ></or-mwc-input>
239
- <!-- if identity provider is set to use email as username, make it required -->
240
- <or-mwc-input id="new-email" class="validate"
241
- .label="${i18next.t("email")}"
242
- .type="${InputType.EMAIL}"
243
- ?required="${registrationEmailAsUsername}"
244
- ?readonly="${(!!(user === null || user === void 0 ? void 0 : user.id) && registrationEmailAsUsername) || readonly}"
245
- .disabled="${!user || (!!(user === null || user === void 0 ? void 0 : user.id) && registrationEmailAsUsername)}"
246
- pattern="^[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w]{2,4}$"
247
- .validationMessage="${i18next.t("invalidEmail")}"
248
- .value="${user === null || user === void 0 ? void 0 : user.email}" autocomplete="false"
237
+ }}"
238
+ ></or-mwc-input>
239
+ <!-- if identity provider is set to use email as username, make it required -->
240
+ <or-mwc-input id="new-email" class="validate"
241
+ .label="${i18next.t("email")}"
242
+ .type="${InputType.EMAIL}"
243
+ ?required="${registrationEmailAsUsername}"
244
+ ?readonly="${(!!(user === null || user === void 0 ? void 0 : user.id) && registrationEmailAsUsername) || readonly}"
245
+ .disabled="${!user || (!!(user === null || user === void 0 ? void 0 : user.id) && registrationEmailAsUsername)}"
246
+ pattern="^[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w]{2,4}$"
247
+ .validationMessage="${i18next.t("invalidEmail")}"
248
+ .value="${user === null || user === void 0 ? void 0 : user.email}" autocomplete="false"
249
249
  @or-mwc-input-changed="${(e) => {
250
250
  user.email = e.detail.value;
251
251
  onchange === null || onchange === void 0 ? void 0 : onchange(user, true, this._isInvalid());
252
- }}"
253
- ></or-mwc-input>
254
- <or-mwc-input id="new-firstName" class="validate"
255
- .label="${i18next.t("firstName")}"
256
- .type="${InputType.TEXT}"
257
- ?readonly="${readonly}"
258
- .disabled="${!user}"
259
- minLength="5" autocomplete="false"
260
- .value="${user === null || user === void 0 ? void 0 : user.firstName}"
252
+ }}"
253
+ ></or-mwc-input>
254
+ <or-mwc-input id="new-firstName" class="validate"
255
+ .label="${i18next.t("firstName")}"
256
+ .type="${InputType.TEXT}"
257
+ ?readonly="${readonly}"
258
+ .disabled="${!user}"
259
+ minLength="5" autocomplete="false"
260
+ .value="${user === null || user === void 0 ? void 0 : user.firstName}"
261
261
  @or-mwc-input-changed="${(e) => {
262
262
  user.firstName = e.detail.value;
263
263
  onchange === null || onchange === void 0 ? void 0 : onchange(user, true, this._isInvalid());
264
- }}"
265
- ></or-mwc-input>
266
- <or-mwc-input id="new-surname" class="validate"
267
- .label="${i18next.t("surname")}"
268
- .type="${InputType.TEXT}"
269
- ?readonly="${readonly}"
270
- .disabled="${!user}"
271
- minLength="1" autocomplete="false"
272
- .value="${user === null || user === void 0 ? void 0 : user.lastName}"
264
+ }}"
265
+ ></or-mwc-input>
266
+ <or-mwc-input id="new-surname" class="validate"
267
+ .label="${i18next.t("surname")}"
268
+ .type="${InputType.TEXT}"
269
+ ?readonly="${readonly}"
270
+ .disabled="${!user}"
271
+ minLength="1" autocomplete="false"
272
+ .value="${user === null || user === void 0 ? void 0 : user.lastName}"
273
273
  @or-mwc-input-changed="${(e) => {
274
274
  user.lastName = e.detail.value;
275
275
  onchange === null || onchange === void 0 ? void 0 : onchange(user, true, this._isInvalid());
276
- }}">
277
- </or-mwc-input>
278
- </div>
279
- <div class="column">
280
- <h5>${i18next.t("password")}</h5>
281
- ${registrationEmailAsUsername ? html `
282
- <!-- Reset password button when email as username is configured -->
283
- <or-mwc-input id="reset-password" raised
284
- .label="${i18next.t("resetPassword")}"
285
- .type="${InputType.BUTTON}"
286
- .disabled="${!user.email}"
287
- @or-mwc-input-changed="${(e) => this._onResetPasswordBtnClick(e)}"
288
- ></or-mwc-input>
289
- ` : html `
290
- <!-- Direct password input fields when email as username not configured -->
291
- <or-mwc-input id="new-password" class="validate"
292
- .label="${i18next.t("password")}"
293
- .type="${InputType.PASSWORD}"
294
- ?readonly="${readonly}"
295
- .disabled="${!user}"
296
- min="1" autocomplete="false"
276
+ }}">
277
+ </or-mwc-input>
278
+ </div>
279
+ <div class="column">
280
+ <h5>${i18next.t("password")}</h5>
281
+ ${registrationEmailAsUsername ? html `
282
+ <!-- Reset password button when email as username is configured -->
283
+ <or-mwc-input id="reset-password" raised
284
+ .label="${i18next.t("resetPassword")}"
285
+ .type="${InputType.BUTTON}"
286
+ .disabled="${!user.email}"
287
+ @or-mwc-input-changed="${(e) => this._onResetPasswordBtnClick(e)}"
288
+ ></or-mwc-input>
289
+ ` : html `
290
+ <!-- Direct password input fields when email as username not configured -->
291
+ <or-mwc-input id="new-password" class="validate"
292
+ .label="${i18next.t("password")}"
293
+ .type="${InputType.PASSWORD}"
294
+ ?readonly="${readonly}"
295
+ .disabled="${!user}"
296
+ min="1" autocomplete="false"
297
297
  @or-mwc-input-changed="${(_e) => {
298
298
  const changed = this._onPasswordChanged(user);
299
299
  onchange === null || onchange === void 0 ? void 0 : onchange(user, changed, this._isInvalid());
300
- }}"
301
- ></or-mwc-input>
302
- <or-mwc-input id="new-repeatPassword"
303
- .label="${i18next.t("repeatPassword")}"
304
- .type="${InputType.PASSWORD}"
305
- helperPersistent
306
- ?readonly="${readonly}"
307
- .disabled="${!user}"
308
- min="1" autocomplete="false"
300
+ }}"
301
+ ></or-mwc-input>
302
+ <or-mwc-input id="new-repeatPassword"
303
+ .label="${i18next.t("repeatPassword")}"
304
+ .type="${InputType.PASSWORD}"
305
+ helperPersistent
306
+ ?readonly="${readonly}"
307
+ .disabled="${!user}"
308
+ min="1" autocomplete="false"
309
309
  @or-mwc-input-changed="${(_e) => {
310
310
  const changed = this._onPasswordChanged(user);
311
311
  onchange === null || onchange === void 0 ? void 0 : onchange(user, changed, this._isInvalid());
312
- }}"
313
- ></or-mwc-input>
314
- ${when(this._passwordPolicy, () => until(this._getPasswordPolicyTemplate(user, this._passwordPolicy)))}
315
- `}
316
- </div>
317
- </div>
318
-
312
+ }}"
313
+ ></or-mwc-input>
314
+ ${when(this._passwordPolicy, () => until(this._getPasswordPolicyTemplate(user, this._passwordPolicy)))}
315
+ `}
316
+ </div>
317
+ </div>
318
+
319
319
  `;
320
320
  });
321
321
  }
@@ -326,15 +326,15 @@ let PageAccount = class PageAccount extends Page {
326
326
  return __awaiter(this, void 0, void 0, function* () {
327
327
  const invalid = this._isInvalid();
328
328
  const dirty = this._isDirty();
329
- return html `
330
- <div class="row" style="justify-content: end; margin-top: 20px;">
331
- <or-mwc-input id="savebtn" style="margin: 0;" raised
332
- .label="${i18next.t(user.id ? "save" : "create")}"
333
- .type="${InputType.BUTTON}"
334
- .disabled="${invalid || !dirty}"
335
- @or-mwc-input-changed="${(e) => this._onSaveBtnClick(e)}"
336
- ></or-mwc-input>
337
- </div>
329
+ return html `
330
+ <div class="row" style="justify-content: end; margin-top: 20px;">
331
+ <or-mwc-input id="savebtn" style="margin: 0;" raised
332
+ .label="${i18next.t(user.id ? "save" : "create")}"
333
+ .type="${InputType.BUTTON}"
334
+ .disabled="${invalid || !dirty}"
335
+ @or-mwc-input-changed="${(e) => this._onSaveBtnClick(e)}"
336
+ ></or-mwc-input>
337
+ </div>
338
338
  `;
339
339
  });
340
340
  }
@@ -486,66 +486,66 @@ let PageAccount = class PageAccount extends Page {
486
486
  const policyTexts = [];
487
487
  // Minimum / maximum length warning
488
488
  if (policies.includes("length") && policies.includes("maxLength")) {
489
- policyTexts.push(html `
489
+ policyTexts.push(html `
490
490
  <or-translate value="password-policy-invalid-length" .options="${{
491
491
  0: policyMap.get("length"),
492
492
  1: policyMap.get("maxLength")
493
493
  }}"></or-translate>`);
494
494
  }
495
495
  else if (policies.includes("length")) {
496
- policyTexts.push(html `
497
- <or-translate value="password-policy-invalid-length-too-short"
496
+ policyTexts.push(html `
497
+ <or-translate value="password-policy-invalid-length-too-short"
498
498
  .options="${{ 0: policyMap.get("length") }}"></or-translate>`);
499
499
  }
500
500
  else if (policies.includes("maxLength")) {
501
- policyTexts.push(html `
502
- <or-translate value="password-policy-invalid-length-too-long"
501
+ policyTexts.push(html `
502
+ <or-translate value="password-policy-invalid-length-too-long"
503
503
  .options="${{ 0: policyMap.get("maxLength") }}"></or-translate>`);
504
504
  }
505
505
  // Special characters
506
506
  if (policies.includes("specialChars")) {
507
507
  const value = policyMap.get("specialChars");
508
508
  const translation = value === "1" ? "password-policy-special-chars-single" : "password-policy-special-chars";
509
- policyTexts.push(html `
509
+ policyTexts.push(html `
510
510
  <or-translate value="${translation}" .options="${{ 0: value }}"></or-translate>`);
511
511
  }
512
512
  // Digits/numbers
513
513
  if (policies.includes("digits")) {
514
514
  const value = policyMap.get("digits");
515
515
  const translation = value === "1" ? "password-policy-digits-single" : "password-policy-digits";
516
- policyTexts.push(html `
516
+ policyTexts.push(html `
517
517
  <or-translate value="${translation}" .options="${{ 0: value }}"></or-translate>`);
518
518
  }
519
519
  // Uppercase / lowercase letters
520
520
  if (policies.includes("upperCase")) {
521
521
  const value = policyMap.get("upperCase");
522
522
  const translation = value === "1" ? "password-policy-uppercase-single" : "password-policy-uppercase";
523
- policyTexts.push(html `
523
+ policyTexts.push(html `
524
524
  <or-translate value="${translation}" .options="${{ 0: value }}"></or-translate>`);
525
525
  }
526
526
  // Warn for recently used passwords
527
527
  if (policies.includes("passwordHistory")) {
528
- policyTexts.push(html `
528
+ policyTexts.push(html `
529
529
  <or-translate value="password-policy-recently-used"></or-translate>`);
530
530
  }
531
531
  // Cannot be username and/or email
532
532
  if (policies.includes("notUsername") && policies.includes("notEmail")) {
533
- policyTexts.push(html `
533
+ policyTexts.push(html `
534
534
  <or-translate value="password-policy-not-email-username"></or-translate>`);
535
535
  }
536
536
  else if (policies.includes("notUsername")) {
537
- policyTexts.push(html `
537
+ policyTexts.push(html `
538
538
  <or-translate value="password-policy-not-username"></or-translate>`);
539
539
  }
540
540
  else if (policies.includes("notEmail")) {
541
- policyTexts.push(html `
541
+ policyTexts.push(html `
542
542
  <or-translate value="password-policy-not-email"></or-translate>`);
543
543
  }
544
- return html `
545
- <ul>
546
- ${map(policyTexts, text => html `
547
- <li>${text}</li>`)}
548
- </ul>
544
+ return html `
545
+ <ul>
546
+ ${map(policyTexts, text => html `
547
+ <li>${text}</li>`)}
548
+ </ul>
549
549
  `;
550
550
  });
551
551
  }