@descope/flow-components 3.9.2 → 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.
- package/dist/fm/222.js +1 -1
- package/dist/fm/222.js.map +1 -1
- package/dist/fm/467.js +1 -1
- package/dist/fm/467.js.map +1 -1
- package/dist/fm/741.js +1 -1
- package/dist/fm/741.js.map +1 -1
- package/dist/fm/985.js +1 -1
- package/dist/fm/985.js.map +1 -1
- package/dist/fm/@mf-types/compiled-types/NewPassword/NewPassword.d.ts +4 -0
- package/dist/fm/__federation_expose_componentClasses.js +1 -1
- package/dist/fm/__federation_expose_componentClasses.js.map +1 -1
- package/dist/fm/__federation_expose_components.js +1 -1
- package/dist/fm/__federation_expose_theme.js +1 -1
- package/dist/fm/__federation_expose_theme.js.map +1 -1
- package/dist/fm/flowComponents.js +1 -1
- package/dist/fm/flowComponents.js.map +1 -1
- package/dist/fm/main.js +1 -1
- package/dist/fm/main.js.map +1 -1
- package/dist/fm/mf-manifest.json +1 -1
- package/dist/fm/mf-stats.json +1 -1
- package/dist/index.cjs.js +111 -19
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +37 -11
- package/dist/types/NewPassword/NewPassword.d.ts +4 -0
- package/package.json +2 -2
package/dist/fm/mf-manifest.json
CHANGED
package/dist/fm/mf-stats.json
CHANGED
package/dist/index.cjs.js
CHANGED
|
@@ -97739,6 +97739,8 @@ descope-enriched-text {
|
|
|
97739
97739
|
'data-password-policy-value-minlength',
|
|
97740
97740
|
'data-password-policy-value-passwordstrength',
|
|
97741
97741
|
'data-password-policy-actual-passwordstrength',
|
|
97742
|
+
'data-password-policy-value-disallowedchars',
|
|
97743
|
+
'data-password-policy-value-email',
|
|
97742
97744
|
];
|
|
97743
97745
|
const dataAttrs = ['data', 'active-policies', 'overrides', ...overrideAttrs];
|
|
97744
97746
|
const policyAttrs = ['label', 'value', ...dataAttrs];
|
|
@@ -97857,6 +97859,46 @@ descope-enriched-text {
|
|
|
97857
97859
|
};
|
|
97858
97860
|
}
|
|
97859
97861
|
}
|
|
97862
|
+
|
|
97863
|
+
// disallowedchars: this stores the configured char list in
|
|
97864
|
+
// overrides.disallowedchars.value so the message can interpolate
|
|
97865
|
+
// `{{value}}`. The regex pattern itself is built upstream (orchestrator
|
|
97866
|
+
// or caller) and shipped on the policy entry — it is not derived from
|
|
97867
|
+
// this override. When the attribute is cleared, drop the override so
|
|
97868
|
+
// the panel doesn't keep stale data.
|
|
97869
|
+
if (attrName === 'data-password-policy-value-disallowedchars') {
|
|
97870
|
+
if (newValue) {
|
|
97871
|
+
this.#overrides = {
|
|
97872
|
+
...this.#overrides,
|
|
97873
|
+
disallowedchars: {
|
|
97874
|
+
...this.#overrides?.disallowedchars,
|
|
97875
|
+
value: newValue,
|
|
97876
|
+
},
|
|
97877
|
+
};
|
|
97878
|
+
} else if (this.#overrides?.disallowedchars) {
|
|
97879
|
+
const { disallowedchars: _drop, ...rest } = this.#overrides;
|
|
97880
|
+
this.#overrides = rest;
|
|
97881
|
+
}
|
|
97882
|
+
}
|
|
97883
|
+
|
|
97884
|
+
// disallowemail: stash the user's email so the STR_NEQ_CI comparator
|
|
97885
|
+
// has an `expected` to compare against the live password value. Clear
|
|
97886
|
+
// the override when the attribute is removed/empty so we don't keep
|
|
97887
|
+
// blocking against a previous user's email.
|
|
97888
|
+
if (attrName === 'data-password-policy-value-email') {
|
|
97889
|
+
if (newValue) {
|
|
97890
|
+
this.#overrides = {
|
|
97891
|
+
...this.#overrides,
|
|
97892
|
+
disallowemail: {
|
|
97893
|
+
...this.#overrides?.disallowemail,
|
|
97894
|
+
expected: newValue,
|
|
97895
|
+
},
|
|
97896
|
+
};
|
|
97897
|
+
} else if (this.#overrides?.disallowemail) {
|
|
97898
|
+
const { disallowemail: _drop, ...rest } = this.#overrides;
|
|
97899
|
+
this.#overrides = rest;
|
|
97900
|
+
}
|
|
97901
|
+
}
|
|
97860
97902
|
}
|
|
97861
97903
|
|
|
97862
97904
|
this.renderItems(this.#availablePolicies, this.#activePolicies, this.#overrides);
|
|
@@ -97921,6 +97963,7 @@ descope-enriched-text {
|
|
|
97921
97963
|
}
|
|
97922
97964
|
|
|
97923
97965
|
const { pattern, message, data, compare } = policy;
|
|
97966
|
+
const normalizedCompare = typeof compare === 'string' ? compare.toUpperCase() : compare;
|
|
97924
97967
|
|
|
97925
97968
|
if ((!pattern && !compare) || !message) {
|
|
97926
97969
|
return results;
|
|
@@ -97934,9 +97977,23 @@ descope-enriched-text {
|
|
|
97934
97977
|
if (pattern) {
|
|
97935
97978
|
const exp = new RegExp(interpolateString(pattern, data));
|
|
97936
97979
|
validationResult.valid = exp.test(this.value);
|
|
97980
|
+
} else if (normalizedCompare === 'STR_NEQ_CI') {
|
|
97981
|
+
// Compare the live password against the configured string AND its
|
|
97982
|
+
// local-part (before '@'), case-insensitively. Used by the
|
|
97983
|
+
// disallowemail policy.
|
|
97984
|
+
const expected = (data?.expected ?? '').toLowerCase();
|
|
97985
|
+
const actual = (this.value ?? '').toLowerCase();
|
|
97986
|
+
if (!expected || !actual) {
|
|
97987
|
+
// nothing to compare → mark valid so we don't block the flow
|
|
97988
|
+
validationResult.valid = true;
|
|
97989
|
+
} else {
|
|
97990
|
+
const at = expected.indexOf('@');
|
|
97991
|
+
const localPart = at > 0 ? expected.slice(0, at) : expected;
|
|
97992
|
+
validationResult.valid = actual !== expected && actual !== localPart;
|
|
97993
|
+
}
|
|
97937
97994
|
} else if (compare) {
|
|
97938
97995
|
validationResult.valid = this.compareValues(
|
|
97939
|
-
|
|
97996
|
+
normalizedCompare,
|
|
97940
97997
|
data?.expected ?? -1,
|
|
97941
97998
|
data?.actual ?? -1
|
|
97942
97999
|
);
|
|
@@ -97952,13 +98009,18 @@ descope-enriched-text {
|
|
|
97952
98009
|
return !this.validate().some(({ valid }) => valid === false);
|
|
97953
98010
|
}
|
|
97954
98011
|
|
|
97955
|
-
|
|
98012
|
+
buildValidationItem({ valid, message }) {
|
|
97956
98013
|
const status = !this.value ? 'none' : valid;
|
|
97957
|
-
|
|
97958
|
-
|
|
97959
|
-
|
|
97960
|
-
|
|
97961
|
-
|
|
98014
|
+
const li = document.createElement('li');
|
|
98015
|
+
li.className = 'item';
|
|
98016
|
+
li.dataset.valid = status;
|
|
98017
|
+
const span = document.createElement('span');
|
|
98018
|
+
span.className = 'message';
|
|
98019
|
+
// `textContent` handles any tenant-configured string in `message` safely
|
|
98020
|
+
// (e.g. the disallowedchars list) without needing to escape HTML.
|
|
98021
|
+
span.textContent = message ?? '';
|
|
98022
|
+
li.appendChild(span);
|
|
98023
|
+
return li;
|
|
97962
98024
|
}
|
|
97963
98025
|
|
|
97964
98026
|
renderItems(availablePolicies, activePolicies) {
|
|
@@ -97966,7 +98028,9 @@ descope-enriched-text {
|
|
|
97966
98028
|
return;
|
|
97967
98029
|
}
|
|
97968
98030
|
|
|
97969
|
-
this.list.
|
|
98031
|
+
this.list.replaceChildren(
|
|
98032
|
+
...this.validate().map(this.buildValidationItem.bind(this)),
|
|
98033
|
+
);
|
|
97970
98034
|
}
|
|
97971
98035
|
|
|
97972
98036
|
updateLabel(val) {
|
|
@@ -98067,6 +98131,8 @@ descope-enriched-text {
|
|
|
98067
98131
|
'available-policies',
|
|
98068
98132
|
'data-password-policy-value-minlength',
|
|
98069
98133
|
'data-password-policy-value-passwordstrength',
|
|
98134
|
+
'data-password-policy-value-disallowedchars',
|
|
98135
|
+
'data-password-policy-value-email',
|
|
98070
98136
|
'label-type',
|
|
98071
98137
|
'manual-visibility-toggle',
|
|
98072
98138
|
],
|
|
@@ -107117,6 +107183,11 @@ const Loader = React__default.default.forwardRef(({ variant, color, ...restProps
|
|
|
107117
107183
|
|
|
107118
107184
|
const Logo = React__default.default.forwardRef(({ width, height, ...props }, ref) => (React__default.default.createElement("descope-logo", { "st-width": width, "st-height": height, ref: ref, ...props })));
|
|
107119
107185
|
|
|
107186
|
+
// Escape characters that have a special meaning inside a JS regex character
|
|
107187
|
+
// class so they appear as literals (used to build the disallowedchars regex
|
|
107188
|
+
// from a tenant-configured chars list).
|
|
107189
|
+
const escapeRegexClassChars = (s) => s.replace(/[\\\]\-^]/g, '\\$&');
|
|
107190
|
+
const buildDisallowedCharsPattern = (chars) => chars ? `^[^${escapeRegexClassChars(chars)}]*$` : '';
|
|
107120
107191
|
const defaultProps = {
|
|
107121
107192
|
'has-validation': false,
|
|
107122
107193
|
'policy-label': 'Passwords must have:',
|
|
@@ -107134,6 +107205,7 @@ const defaultProps = {
|
|
|
107134
107205
|
'data-password-policy-pattern-nonalphanumeric': '[^a-zA-Z0-9]',
|
|
107135
107206
|
// non-user-editable comparisons
|
|
107136
107207
|
'data-password-policy-compare-passwordstrength': 'GTE',
|
|
107208
|
+
'data-password-policy-compare-disallowemail': 'STR_NEQ_CI',
|
|
107137
107209
|
// props to override with data from policy
|
|
107138
107210
|
'data-password-policy-value-minlength': '8',
|
|
107139
107211
|
// translatable props
|
|
@@ -107144,30 +107216,50 @@ const defaultProps = {
|
|
|
107144
107216
|
'data-password-policy-message-number': '1 number',
|
|
107145
107217
|
'data-password-policy-message-nonalphanumeric': '1 symbol',
|
|
107146
107218
|
'data-password-policy-message-passwordstrength': 'Password strength',
|
|
107219
|
+
'data-password-policy-message-disallowedchars': 'Does not contain: {{value}}',
|
|
107220
|
+
'data-password-policy-message-disallowemail': 'Does not match your email',
|
|
107147
107221
|
'st-policy-preview-background-color': 'transparent',
|
|
107148
107222
|
'st-policy-preview-padding': '0'
|
|
107149
107223
|
};
|
|
107150
107224
|
const NewPassword = React__default.default.forwardRef((props, ref) => {
|
|
107151
107225
|
const mergedProps = { ...defaultProps, ...props };
|
|
107226
|
+
// Dynamic key lookups (`data-password-policy-${kind}-${id}`) below sit
|
|
107227
|
+
// outside the typed Props surface, so we read them through a narrow
|
|
107228
|
+
// Record alias rather than widening the whole mergedProps to `any`.
|
|
107229
|
+
const mergedPropsByKey = mergedProps;
|
|
107152
107230
|
/* this logic is cloned in the orchestration service (context.go file)
|
|
107153
|
-
|
|
107154
|
-
|
|
107155
|
-
const availablePolicies = [
|
|
107231
|
+
* make sure to update both places when changing it
|
|
107232
|
+
*/
|
|
107233
|
+
const availablePolicies = JSON.stringify([
|
|
107156
107234
|
'minlength',
|
|
107157
107235
|
'lowercase',
|
|
107158
107236
|
'uppercase',
|
|
107159
107237
|
'anyletter',
|
|
107160
107238
|
'number',
|
|
107161
107239
|
'nonalphanumeric',
|
|
107162
|
-
'passwordstrength'
|
|
107163
|
-
|
|
107164
|
-
|
|
107165
|
-
|
|
107166
|
-
|
|
107167
|
-
|
|
107168
|
-
|
|
107240
|
+
'passwordstrength',
|
|
107241
|
+
'disallowedchars',
|
|
107242
|
+
'disallowemail'
|
|
107243
|
+
].map((id) => {
|
|
107244
|
+
const entry = {
|
|
107245
|
+
id,
|
|
107246
|
+
message: mergedPropsByKey[`data-password-policy-message-${id}`],
|
|
107247
|
+
pattern: mergedPropsByKey[`data-password-policy-pattern-${id}`],
|
|
107248
|
+
compare: mergedPropsByKey[`data-password-policy-compare-${id}`],
|
|
107249
|
+
data: mergedPropsByKey[`data-password-policy-data-${id}`]
|
|
107250
|
+
};
|
|
107251
|
+
// disallowedchars: the pattern is `^[^<escaped chars>]*$`, built from
|
|
107252
|
+
// the configured chars list. Done here (rather than as a static
|
|
107253
|
+
// pattern with a `{{value}}` placeholder) so chars like `]`, `^`, `-`,
|
|
107254
|
+
// `\` are escaped instead of breaking the character class.
|
|
107255
|
+
if (id === 'disallowedchars') {
|
|
107256
|
+
const chars = mergedPropsByKey['data-password-policy-value-disallowedchars'] || '';
|
|
107257
|
+
entry.pattern = buildDisallowedCharsPattern(chars);
|
|
107258
|
+
entry.data = { value: chars };
|
|
107259
|
+
}
|
|
107260
|
+
return entry;
|
|
107169
107261
|
}));
|
|
107170
|
-
return (React__default.default.createElement("descope-new-password", { ...mergedProps, ref: ref, "available-policies":
|
|
107262
|
+
return (React__default.default.createElement("descope-new-password", { ...mergedProps, ref: ref, "available-policies": availablePolicies }));
|
|
107171
107263
|
});
|
|
107172
107264
|
|
|
107173
107265
|
const PhoneCountrySelection = React__default.default.forwardRef((props, ref) => React__default.default.createElement("descope-phone-field", { ...props, ref: ref }));
|
package/dist/index.d.ts
CHANGED
|
@@ -355,7 +355,11 @@ type Props$H = {
|
|
|
355
355
|
'data-password-policy-message-number'?: string;
|
|
356
356
|
'data-password-policy-message-nonalphanumeric'?: string;
|
|
357
357
|
'data-password-policy-message-passwordstrength'?: string;
|
|
358
|
+
'data-password-policy-message-disallowedchars'?: string;
|
|
359
|
+
'data-password-policy-message-disallowemail'?: string;
|
|
358
360
|
'data-password-policy-value-minlength'?: string;
|
|
361
|
+
'data-password-policy-value-disallowedchars'?: string;
|
|
362
|
+
'data-password-policy-value-email'?: string;
|
|
359
363
|
'st-policy-preview-background-color'?: string;
|
|
360
364
|
'st-policy-preview-padding'?: string;
|
|
361
365
|
};
|
package/dist/index.esm.js
CHANGED
|
@@ -283,6 +283,11 @@ const Loader = React.forwardRef(({ variant, color, ...restProps }, ref) => {
|
|
|
283
283
|
|
|
284
284
|
const Logo = React.forwardRef(({ width, height, ...props }, ref) => (React.createElement("descope-logo", { "st-width": width, "st-height": height, ref: ref, ...props })));
|
|
285
285
|
|
|
286
|
+
// Escape characters that have a special meaning inside a JS regex character
|
|
287
|
+
// class so they appear as literals (used to build the disallowedchars regex
|
|
288
|
+
// from a tenant-configured chars list).
|
|
289
|
+
const escapeRegexClassChars = (s) => s.replace(/[\\\]\-^]/g, '\\$&');
|
|
290
|
+
const buildDisallowedCharsPattern = (chars) => chars ? `^[^${escapeRegexClassChars(chars)}]*$` : '';
|
|
286
291
|
const defaultProps = {
|
|
287
292
|
'has-validation': false,
|
|
288
293
|
'policy-label': 'Passwords must have:',
|
|
@@ -300,6 +305,7 @@ const defaultProps = {
|
|
|
300
305
|
'data-password-policy-pattern-nonalphanumeric': '[^a-zA-Z0-9]',
|
|
301
306
|
// non-user-editable comparisons
|
|
302
307
|
'data-password-policy-compare-passwordstrength': 'GTE',
|
|
308
|
+
'data-password-policy-compare-disallowemail': 'STR_NEQ_CI',
|
|
303
309
|
// props to override with data from policy
|
|
304
310
|
'data-password-policy-value-minlength': '8',
|
|
305
311
|
// translatable props
|
|
@@ -310,30 +316,50 @@ const defaultProps = {
|
|
|
310
316
|
'data-password-policy-message-number': '1 number',
|
|
311
317
|
'data-password-policy-message-nonalphanumeric': '1 symbol',
|
|
312
318
|
'data-password-policy-message-passwordstrength': 'Password strength',
|
|
319
|
+
'data-password-policy-message-disallowedchars': 'Does not contain: {{value}}',
|
|
320
|
+
'data-password-policy-message-disallowemail': 'Does not match your email',
|
|
313
321
|
'st-policy-preview-background-color': 'transparent',
|
|
314
322
|
'st-policy-preview-padding': '0'
|
|
315
323
|
};
|
|
316
324
|
const NewPassword = React.forwardRef((props, ref) => {
|
|
317
325
|
const mergedProps = { ...defaultProps, ...props };
|
|
326
|
+
// Dynamic key lookups (`data-password-policy-${kind}-${id}`) below sit
|
|
327
|
+
// outside the typed Props surface, so we read them through a narrow
|
|
328
|
+
// Record alias rather than widening the whole mergedProps to `any`.
|
|
329
|
+
const mergedPropsByKey = mergedProps;
|
|
318
330
|
/* this logic is cloned in the orchestration service (context.go file)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const availablePolicies = [
|
|
331
|
+
* make sure to update both places when changing it
|
|
332
|
+
*/
|
|
333
|
+
const availablePolicies = JSON.stringify([
|
|
322
334
|
'minlength',
|
|
323
335
|
'lowercase',
|
|
324
336
|
'uppercase',
|
|
325
337
|
'anyletter',
|
|
326
338
|
'number',
|
|
327
339
|
'nonalphanumeric',
|
|
328
|
-
'passwordstrength'
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
340
|
+
'passwordstrength',
|
|
341
|
+
'disallowedchars',
|
|
342
|
+
'disallowemail'
|
|
343
|
+
].map((id) => {
|
|
344
|
+
const entry = {
|
|
345
|
+
id,
|
|
346
|
+
message: mergedPropsByKey[`data-password-policy-message-${id}`],
|
|
347
|
+
pattern: mergedPropsByKey[`data-password-policy-pattern-${id}`],
|
|
348
|
+
compare: mergedPropsByKey[`data-password-policy-compare-${id}`],
|
|
349
|
+
data: mergedPropsByKey[`data-password-policy-data-${id}`]
|
|
350
|
+
};
|
|
351
|
+
// disallowedchars: the pattern is `^[^<escaped chars>]*$`, built from
|
|
352
|
+
// the configured chars list. Done here (rather than as a static
|
|
353
|
+
// pattern with a `{{value}}` placeholder) so chars like `]`, `^`, `-`,
|
|
354
|
+
// `\` are escaped instead of breaking the character class.
|
|
355
|
+
if (id === 'disallowedchars') {
|
|
356
|
+
const chars = mergedPropsByKey['data-password-policy-value-disallowedchars'] || '';
|
|
357
|
+
entry.pattern = buildDisallowedCharsPattern(chars);
|
|
358
|
+
entry.data = { value: chars };
|
|
359
|
+
}
|
|
360
|
+
return entry;
|
|
335
361
|
}));
|
|
336
|
-
return (React.createElement("descope-new-password", { ...mergedProps, ref: ref, "available-policies":
|
|
362
|
+
return (React.createElement("descope-new-password", { ...mergedProps, ref: ref, "available-policies": availablePolicies }));
|
|
337
363
|
});
|
|
338
364
|
|
|
339
365
|
const PhoneCountrySelection = React.forwardRef((props, ref) => React.createElement("descope-phone-field", { ...props, ref: ref }));
|
|
@@ -22,7 +22,11 @@ export type Props = {
|
|
|
22
22
|
'data-password-policy-message-number'?: string;
|
|
23
23
|
'data-password-policy-message-nonalphanumeric'?: string;
|
|
24
24
|
'data-password-policy-message-passwordstrength'?: string;
|
|
25
|
+
'data-password-policy-message-disallowedchars'?: string;
|
|
26
|
+
'data-password-policy-message-disallowemail'?: string;
|
|
25
27
|
'data-password-policy-value-minlength'?: string;
|
|
28
|
+
'data-password-policy-value-disallowedchars'?: string;
|
|
29
|
+
'data-password-policy-value-email'?: string;
|
|
26
30
|
'st-policy-preview-background-color'?: string;
|
|
27
31
|
'st-policy-preview-padding'?: string;
|
|
28
32
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descope/flow-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"webpack-subresource-integrity": "5.2.0-rc.1"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
|
-
"@descope/web-components-ui": "3.
|
|
100
|
+
"@descope/web-components-ui": "3.10.0"
|
|
101
101
|
},
|
|
102
102
|
"peerDependencies": {
|
|
103
103
|
"react": ">= 18"
|