@descope/web-components-ui 3.9.1 → 3.10.0

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.
@@ -18164,6 +18164,8 @@ const overrideAttrs = [
18164
18164
  'data-password-policy-value-minlength',
18165
18165
  'data-password-policy-value-passwordstrength',
18166
18166
  'data-password-policy-actual-passwordstrength',
18167
+ 'data-password-policy-value-disallowedchars',
18168
+ 'data-password-policy-value-email',
18167
18169
  ];
18168
18170
  const dataAttrs = ['data', 'active-policies', 'overrides', ...overrideAttrs];
18169
18171
  const policyAttrs = ['label', 'value', ...dataAttrs];
@@ -18282,6 +18284,46 @@ class RawPolicyValidation extends createBaseClass({ componentName: componentName
18282
18284
  };
18283
18285
  }
18284
18286
  }
18287
+
18288
+ // disallowedchars: this stores the configured char list in
18289
+ // overrides.disallowedchars.value so the message can interpolate
18290
+ // `{{value}}`. The regex pattern itself is built upstream (orchestrator
18291
+ // or caller) and shipped on the policy entry — it is not derived from
18292
+ // this override. When the attribute is cleared, drop the override so
18293
+ // the panel doesn't keep stale data.
18294
+ if (attrName === 'data-password-policy-value-disallowedchars') {
18295
+ if (newValue) {
18296
+ this.#overrides = {
18297
+ ...this.#overrides,
18298
+ disallowedchars: {
18299
+ ...this.#overrides?.disallowedchars,
18300
+ value: newValue,
18301
+ },
18302
+ };
18303
+ } else if (this.#overrides?.disallowedchars) {
18304
+ const { disallowedchars: _drop, ...rest } = this.#overrides;
18305
+ this.#overrides = rest;
18306
+ }
18307
+ }
18308
+
18309
+ // disallowemail: stash the user's email so the STR_NEQ_CI comparator
18310
+ // has an `expected` to compare against the live password value. Clear
18311
+ // the override when the attribute is removed/empty so we don't keep
18312
+ // blocking against a previous user's email.
18313
+ if (attrName === 'data-password-policy-value-email') {
18314
+ if (newValue) {
18315
+ this.#overrides = {
18316
+ ...this.#overrides,
18317
+ disallowemail: {
18318
+ ...this.#overrides?.disallowemail,
18319
+ expected: newValue,
18320
+ },
18321
+ };
18322
+ } else if (this.#overrides?.disallowemail) {
18323
+ const { disallowemail: _drop, ...rest } = this.#overrides;
18324
+ this.#overrides = rest;
18325
+ }
18326
+ }
18285
18327
  }
18286
18328
 
18287
18329
  this.renderItems(this.#availablePolicies, this.#activePolicies, this.#overrides);
@@ -18346,6 +18388,7 @@ class RawPolicyValidation extends createBaseClass({ componentName: componentName
18346
18388
  }
18347
18389
 
18348
18390
  const { pattern, message, data, compare } = policy;
18391
+ const normalizedCompare = typeof compare === 'string' ? compare.toUpperCase() : compare;
18349
18392
 
18350
18393
  if ((!pattern && !compare) || !message) {
18351
18394
  return results;
@@ -18359,9 +18402,23 @@ class RawPolicyValidation extends createBaseClass({ componentName: componentName
18359
18402
  if (pattern) {
18360
18403
  const exp = new RegExp(interpolateString(pattern, data));
18361
18404
  validationResult.valid = exp.test(this.value);
18405
+ } else if (normalizedCompare === 'STR_NEQ_CI') {
18406
+ // Compare the live password against the configured string AND its
18407
+ // local-part (before '@'), case-insensitively. Used by the
18408
+ // disallowemail policy.
18409
+ const expected = (data?.expected ?? '').toLowerCase();
18410
+ const actual = (this.value ?? '').toLowerCase();
18411
+ if (!expected || !actual) {
18412
+ // nothing to compare → mark valid so we don't block the flow
18413
+ validationResult.valid = true;
18414
+ } else {
18415
+ const at = expected.indexOf('@');
18416
+ const localPart = at > 0 ? expected.slice(0, at) : expected;
18417
+ validationResult.valid = actual !== expected && actual !== localPart;
18418
+ }
18362
18419
  } else if (compare) {
18363
18420
  validationResult.valid = this.compareValues(
18364
- compare,
18421
+ normalizedCompare,
18365
18422
  data?.expected ?? -1,
18366
18423
  data?.actual ?? -1
18367
18424
  );
@@ -18377,13 +18434,18 @@ class RawPolicyValidation extends createBaseClass({ componentName: componentName
18377
18434
  return !this.validate().some(({ valid }) => valid === false);
18378
18435
  }
18379
18436
 
18380
- getValidationItemTemplate({ valid, message }) {
18437
+ buildValidationItem({ valid, message }) {
18381
18438
  const status = !this.value ? 'none' : valid;
18382
- return `
18383
- <li class="item" data-valid="${status}">
18384
- <span class="message">${message}</span>
18385
- </li>
18386
- `;
18439
+ const li = document.createElement('li');
18440
+ li.className = 'item';
18441
+ li.dataset.valid = status;
18442
+ const span = document.createElement('span');
18443
+ span.className = 'message';
18444
+ // `textContent` handles any tenant-configured string in `message` safely
18445
+ // (e.g. the disallowedchars list) without needing to escape HTML.
18446
+ span.textContent = message ?? '';
18447
+ li.appendChild(span);
18448
+ return li;
18387
18449
  }
18388
18450
 
18389
18451
  renderItems(availablePolicies, activePolicies) {
@@ -18391,7 +18453,9 @@ class RawPolicyValidation extends createBaseClass({ componentName: componentName
18391
18453
  return;
18392
18454
  }
18393
18455
 
18394
- this.list.innerHTML = this.validate().map(this.getValidationItemTemplate.bind(this)).join('');
18456
+ this.list.replaceChildren(
18457
+ ...this.validate().map(this.buildValidationItem.bind(this)),
18458
+ );
18395
18459
  }
18396
18460
 
18397
18461
  updateLabel(val) {
@@ -18492,6 +18556,8 @@ const customMixin$4 = (superclass) =>
18492
18556
  'available-policies',
18493
18557
  'data-password-policy-value-minlength',
18494
18558
  'data-password-policy-value-passwordstrength',
18559
+ 'data-password-policy-value-disallowedchars',
18560
+ 'data-password-policy-value-email',
18495
18561
  'label-type',
18496
18562
  'manual-visibility-toggle',
18497
18563
  ],