@frontegg/entitlements-javascript-commons 1.0.0-alpha.10 → 1.0.0-alpha.12
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/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/operations/string/sanitizers.js +2 -2
- package/dist/operations/string/sanitizers.js.map +1 -1
- package/dist/user-entitlements/attributes.utils.d.ts +11 -0
- package/dist/user-entitlements/attributes.utils.js +43 -0
- package/dist/user-entitlements/attributes.utils.js.map +1 -0
- package/dist/user-entitlements/index.d.ts +1 -0
- package/dist/user-entitlements/index.js +1 -0
- package/dist/user-entitlements/index.js.map +1 -1
- package/dist/user-entitlements/is-entitled.evaluator.d.ts +0 -8
- package/dist/user-entitlements/is-entitled.evaluator.js +5 -22
- package/dist/user-entitlements/is-entitled.evaluator.js.map +1 -1
- package/dist/user-entitlements/types.d.ts +3 -3
- package/dist/user-entitlements/types.js.map +1 -1
- package/docs/CHANGELOG.md +14 -0
- package/package.json +5 -1
- package/src/index.ts +2 -0
- package/src/operations/string/sanitizers.ts +2 -2
- package/src/user-entitlements/attributes.utils.ts +44 -0
- package/src/user-entitlements/index.ts +1 -0
- package/src/user-entitlements/is-entitled.evaluator.ts +5 -22
- package/src/user-entitlements/tests/attributes.utils.spec.ts +76 -0
- package/src/user-entitlements/tests/is-entitled.evaluator.spec.ts +12 -29
- package/src/user-entitlements/types.ts +3 -4
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { FeatureFlagEvaluationResult, FeatureFlag, evaluateFeatureFlag } from '.
|
|
|
2
2
|
export { TreatmentEnum, Rule } from './rules';
|
|
3
3
|
export { Condition } from './conditions';
|
|
4
4
|
export { OperationEnum, ConditionValue } from './operations/types';
|
|
5
|
-
export { evaluateIsEntitledToFeature, evaluateIsEntitledToPermissions, CustomAttributes, FronteggAttributes, NotEntitledJustification, UserEntitlementsContext, EntitlementResult, Attributes, } from './user-entitlements';
|
|
5
|
+
export { evaluateIsEntitledToFeature, evaluateIsEntitledToPermissions, prepareAttributes, JwtAttributes, CustomAttributes, FronteggAttributes, NotEntitledJustification, UserEntitlementsContext, EntitlementResult, Attributes, } from './user-entitlements';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NotEntitledJustification = exports.evaluateIsEntitledToPermissions = exports.evaluateIsEntitledToFeature = exports.OperationEnum = exports.TreatmentEnum = exports.evaluateFeatureFlag = void 0;
|
|
3
|
+
exports.NotEntitledJustification = exports.prepareAttributes = exports.evaluateIsEntitledToPermissions = exports.evaluateIsEntitledToFeature = exports.OperationEnum = exports.TreatmentEnum = exports.evaluateFeatureFlag = void 0;
|
|
4
4
|
var feature_flags_1 = require("./feature-flags");
|
|
5
5
|
Object.defineProperty(exports, "evaluateFeatureFlag", { enumerable: true, get: function () { return feature_flags_1.evaluateFeatureFlag; } });
|
|
6
6
|
var rules_1 = require("./rules");
|
|
@@ -10,5 +10,6 @@ Object.defineProperty(exports, "OperationEnum", { enumerable: true, get: functio
|
|
|
10
10
|
var user_entitlements_1 = require("./user-entitlements");
|
|
11
11
|
Object.defineProperty(exports, "evaluateIsEntitledToFeature", { enumerable: true, get: function () { return user_entitlements_1.evaluateIsEntitledToFeature; } });
|
|
12
12
|
Object.defineProperty(exports, "evaluateIsEntitledToPermissions", { enumerable: true, get: function () { return user_entitlements_1.evaluateIsEntitledToPermissions; } });
|
|
13
|
+
Object.defineProperty(exports, "prepareAttributes", { enumerable: true, get: function () { return user_entitlements_1.prepareAttributes; } });
|
|
13
14
|
Object.defineProperty(exports, "NotEntitledJustification", { enumerable: true, get: function () { return user_entitlements_1.NotEntitledJustification; } });
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAgG;AAA7C,oHAAA,mBAAmB,OAAA;AACtE,iCAA8C;AAArC,sGAAA,aAAa,OAAA;AAEtB,4CAAmE;AAA1D,sGAAA,aAAa,OAAA;AACtB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAgG;AAA7C,oHAAA,mBAAmB,OAAA;AACtE,iCAA8C;AAArC,sGAAA,aAAa,OAAA;AAEtB,4CAAmE;AAA1D,sGAAA,aAAa,OAAA;AACtB,yDAW6B;AAV3B,gIAAA,2BAA2B,OAAA;AAC3B,oIAAA,+BAA+B,OAAA;AAC/B,sHAAA,iBAAiB,OAAA;AAIjB,6HAAA,wBAAwB,OAAA"}
|
|
@@ -24,8 +24,8 @@ exports.sanitizeListString = sanitizeListString;
|
|
|
24
24
|
exports.StringSanitizersMapper = {
|
|
25
25
|
[types_1.OperationEnum.Matches]: exports.sanitizeSingleString,
|
|
26
26
|
[types_1.OperationEnum.Contains]: exports.sanitizeListString,
|
|
27
|
-
[types_1.OperationEnum.StartsWith]: exports.
|
|
28
|
-
[types_1.OperationEnum.EndsWith]: exports.
|
|
27
|
+
[types_1.OperationEnum.StartsWith]: exports.sanitizeListString,
|
|
28
|
+
[types_1.OperationEnum.EndsWith]: exports.sanitizeListString,
|
|
29
29
|
[types_1.OperationEnum.InList]: exports.sanitizeListString,
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=sanitizers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizers.js","sourceRoot":"","sources":["../../../src/operations/string/sanitizers.ts"],"names":[],"mappings":";;;AAAA,oCAAsE;AAGtE,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAEzE,MAAM,oBAAoB,GAA4C,CAAC,KAAK,EAAE,EAAE;IACrF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEnH,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,oBAAoB,wBAO/B;AAEK,MAAM,kBAAkB,GAA0C,CAAC,KAAK,EAAE,EAAE;IACjF,MAAM,cAAc,GAClB,KAAK,CAAC,IAAI,KAAK,SAAS,IAAgB,KAAK,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/E,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAgB,EAAE;QAClC,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B;AAEW,QAAA,sBAAsB,GAA6C;IAC9E,CAAC,qBAAa,CAAC,OAAO,CAAC,EAAE,4BAAoB;IAC7C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,UAAU,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"sanitizers.js","sourceRoot":"","sources":["../../../src/operations/string/sanitizers.ts"],"names":[],"mappings":";;;AAAA,oCAAsE;AAGtE,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAEzE,MAAM,oBAAoB,GAA4C,CAAC,KAAK,EAAE,EAAE;IACrF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEnH,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,oBAAoB,wBAO/B;AAEK,MAAM,kBAAkB,GAA0C,CAAC,KAAK,EAAE,EAAE;IACjF,MAAM,cAAc,GAClB,KAAK,CAAC,IAAI,KAAK,SAAS,IAAgB,KAAK,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/E,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAgB,EAAE;QAClC,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B;AAEW,QAAA,sBAAsB,GAA6C;IAC9E,CAAC,qBAAa,CAAC,OAAO,CAAC,EAAE,4BAAoB;IAC7C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,UAAU,CAAC,EAAE,0BAAkB;IAC9C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,MAAM,CAAC,EAAE,0BAAkB;CAC3C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Attributes, JwtAttributes, FronteggAttributes } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Merges both `custom` and `jwt` records, map Frontegg attributes and modifies record keys with corrisponding prefixes
|
|
4
|
+
*
|
|
5
|
+
* Example:
|
|
6
|
+
* Input: { 'custom': { 'customAttribute': 'someValue' }, 'jwt': { 'email': 'user@email.com', other: 'some-vaule' } }
|
|
7
|
+
* Output: { 'customAttribute': 'someValue', 'frontegg.email': 'user@email.com', 'jwt.email': 'user@email.com', 'jwt.other': 'some-vaule' }
|
|
8
|
+
*/
|
|
9
|
+
export declare function prepareAttributes(attributes?: Attributes, customFronteggAttributesMapper?: (jwtAttributes: JwtAttributes) => FronteggAttributes): Record<string, unknown>;
|
|
10
|
+
export declare function defaultFronteggAttributesMapper(jwt: JwtAttributes): FronteggAttributes;
|
|
11
|
+
export declare function modifyObjectKeysWithPrefix(object: Record<string, unknown>, prefix: string): Record<string, unknown>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modifyObjectKeysWithPrefix = exports.defaultFronteggAttributesMapper = exports.prepareAttributes = void 0;
|
|
4
|
+
const flat_1 = require("flat");
|
|
5
|
+
/**
|
|
6
|
+
* Merges both `custom` and `jwt` records, map Frontegg attributes and modifies record keys with corrisponding prefixes
|
|
7
|
+
*
|
|
8
|
+
* Example:
|
|
9
|
+
* Input: { 'custom': { 'customAttribute': 'someValue' }, 'jwt': { 'email': 'user@email.com', other: 'some-vaule' } }
|
|
10
|
+
* Output: { 'customAttribute': 'someValue', 'frontegg.email': 'user@email.com', 'jwt.email': 'user@email.com', 'jwt.other': 'some-vaule' }
|
|
11
|
+
*/
|
|
12
|
+
function prepareAttributes(attributes = {}, customFronteggAttributesMapper) {
|
|
13
|
+
const { custom = {}, jwt = {} } = attributes;
|
|
14
|
+
const flatJwtAttributes = (0, flat_1.flatten)(jwt);
|
|
15
|
+
const fronteggAttributes = customFronteggAttributesMapper
|
|
16
|
+
? customFronteggAttributesMapper(jwt)
|
|
17
|
+
: defaultFronteggAttributesMapper(jwt);
|
|
18
|
+
const fronteggAttributesPrefix = 'frontegg.';
|
|
19
|
+
const jwtAttributesPrefix = 'jwt.';
|
|
20
|
+
return {
|
|
21
|
+
...custom,
|
|
22
|
+
...modifyObjectKeysWithPrefix(fronteggAttributes, fronteggAttributesPrefix),
|
|
23
|
+
...modifyObjectKeysWithPrefix(flatJwtAttributes, jwtAttributesPrefix),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
exports.prepareAttributes = prepareAttributes;
|
|
27
|
+
function defaultFronteggAttributesMapper(jwt) {
|
|
28
|
+
return {
|
|
29
|
+
email: jwt.email,
|
|
30
|
+
emailVerified: jwt.email_verified,
|
|
31
|
+
tenantId: jwt.tenantId,
|
|
32
|
+
userId: jwt.userId,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
exports.defaultFronteggAttributesMapper = defaultFronteggAttributesMapper;
|
|
36
|
+
function modifyObjectKeysWithPrefix(object, prefix) {
|
|
37
|
+
return Object.keys(object).reduce((modifiedObject, currentKey) => {
|
|
38
|
+
modifiedObject[`${prefix}${currentKey}`] = object[currentKey];
|
|
39
|
+
return modifiedObject;
|
|
40
|
+
}, {});
|
|
41
|
+
}
|
|
42
|
+
exports.modifyObjectKeysWithPrefix = modifyObjectKeysWithPrefix;
|
|
43
|
+
//# sourceMappingURL=attributes.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.utils.js","sourceRoot":"","sources":["../../src/user-entitlements/attributes.utils.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAG/B;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAC/B,aAAyB,EAAE,EAC3B,8BAAqF;IAErF,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,UAAU,CAAC;IAC7C,MAAM,iBAAiB,GAAG,IAAA,cAAO,EAA+B,GAAG,CAAC,CAAC;IACrE,MAAM,kBAAkB,GAAG,8BAA8B;QACvD,CAAC,CAAC,8BAA8B,CAAC,GAAG,CAAC;QACrC,CAAC,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,wBAAwB,GAAG,WAAW,CAAC;IAC7C,MAAM,mBAAmB,GAAG,MAAM,CAAC;IAEnC,OAAO;QACL,GAAG,MAAM;QACT,GAAG,0BAA0B,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;QAC3E,GAAG,0BAA0B,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;KACtE,CAAC;AACJ,CAAC;AAjBD,8CAiBC;AAED,SAAgB,+BAA+B,CAAC,GAAkB;IAChE,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAe;QAC1B,aAAa,EAAE,GAAG,CAAC,cAAyB;QAC5C,QAAQ,EAAE,GAAG,CAAC,QAAkB;QAChC,MAAM,EAAE,GAAG,CAAC,MAAgB;KAC7B,CAAC;AACJ,CAAC;AAPD,0EAOC;AAED,SAAgB,0BAA0B,CAAC,MAA+B,EAAE,MAAc;IACxF,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,UAAU,EAAE,EAAE;QAC/D,cAAc,CAAC,GAAG,MAAM,GAAG,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO,cAAc,CAAC;IACxB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AALD,gEAKC"}
|
|
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./is-entitled.evaluator"), exports);
|
|
18
18
|
__exportStar(require("./types"), exports);
|
|
19
|
+
__exportStar(require("./attributes.utils"), exports);
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/user-entitlements/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,0CAAwB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/user-entitlements/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,0CAAwB;AACxB,qDAAmC"}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
1
|
import { EntitlementResult, UserEntitlementsContext, Attributes } from './types';
|
|
2
2
|
export declare function evaluateIsEntitledToFeature(featureKey: string, userEntitlementsContext: UserEntitlementsContext, attributes?: Attributes): EntitlementResult;
|
|
3
3
|
export declare function evaluateIsEntitledToPermissions(permissionKey: string, userEntitlementsContext: UserEntitlementsContext, attributes?: Attributes): EntitlementResult;
|
|
4
|
-
/**
|
|
5
|
-
* Merges the `custom` and `frontegg` Records into a single Record,
|
|
6
|
-
* Alters the `frontegg` Record keys with a prefix
|
|
7
|
-
* Example:
|
|
8
|
-
* Input: { 'custom': { 'customAttribute': 'someValue' }, 'frontegg': { 'email': 'user@email.com' } }
|
|
9
|
-
* Output: { 'customAttribute': 'someValue', 'imported.email': 'user@email.com' }
|
|
10
|
-
*/
|
|
11
|
-
export declare function prepareAttributes(attributes?: Attributes): Record<string, unknown>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.evaluateIsEntitledToPermissions = exports.evaluateIsEntitledToFeature = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const feature_flags_1 = require("../feature-flags");
|
|
6
|
+
const attributes_utils_1 = require("./attributes.utils");
|
|
6
7
|
const rules_1 = require("../rules");
|
|
7
|
-
function evaluateIsEntitledToFeature(featureKey, userEntitlementsContext, attributes) {
|
|
8
|
+
function evaluateIsEntitledToFeature(featureKey, userEntitlementsContext, attributes = {}) {
|
|
8
9
|
const feature = userEntitlementsContext.features[featureKey];
|
|
9
10
|
let hasExpired = false;
|
|
10
11
|
if (feature && feature.expireTime !== null) {
|
|
@@ -14,7 +15,8 @@ function evaluateIsEntitledToFeature(featureKey, userEntitlementsContext, attrib
|
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
if (feature && feature.featureFlag) {
|
|
17
|
-
const
|
|
18
|
+
const preparedAttributes = (0, attributes_utils_1.prepareAttributes)(attributes);
|
|
19
|
+
const { treatment } = (0, feature_flags_1.evaluateFeatureFlag)(feature.featureFlag, preparedAttributes);
|
|
18
20
|
if (treatment === rules_1.TreatmentEnum.True) {
|
|
19
21
|
return { isEntitled: true };
|
|
20
22
|
}
|
|
@@ -53,23 +55,4 @@ exports.evaluateIsEntitledToPermissions = evaluateIsEntitledToPermissions;
|
|
|
53
55
|
function getLinkedFeatures(permissionKey, userEntitlementsContext) {
|
|
54
56
|
return Object.keys(userEntitlementsContext.features).filter((featureKey) => userEntitlementsContext.features[featureKey].linkedPermissions.includes(permissionKey));
|
|
55
57
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Merges the `custom` and `frontegg` Records into a single Record,
|
|
58
|
-
* Alters the `frontegg` Record keys with a prefix
|
|
59
|
-
* Example:
|
|
60
|
-
* Input: { 'custom': { 'customAttribute': 'someValue' }, 'frontegg': { 'email': 'user@email.com' } }
|
|
61
|
-
* Output: { 'customAttribute': 'someValue', 'imported.email': 'user@email.com' }
|
|
62
|
-
*/
|
|
63
|
-
function prepareAttributes(attributes = {}) {
|
|
64
|
-
const { custom = {}, frontegg = {} } = attributes;
|
|
65
|
-
const importedAttributesPrefix = 'imported.'; // Not Final
|
|
66
|
-
return {
|
|
67
|
-
...custom,
|
|
68
|
-
...Object.keys(frontegg).reduce((modifiedImportedAttributes, key) => {
|
|
69
|
-
modifiedImportedAttributes[`${importedAttributesPrefix}${key}`] = frontegg[key];
|
|
70
|
-
return modifiedImportedAttributes;
|
|
71
|
-
}, {}),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
exports.prepareAttributes = prepareAttributes;
|
|
75
58
|
//# sourceMappingURL=is-entitled.evaluator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-entitled.evaluator.js","sourceRoot":"","sources":["../../src/user-entitlements/is-entitled.evaluator.ts"],"names":[],"mappings":";;;AAAA,mCAMiB;
|
|
1
|
+
{"version":3,"file":"is-entitled.evaluator.js","sourceRoot":"","sources":["../../src/user-entitlements/is-entitled.evaluator.ts"],"names":[],"mappings":";;;AAAA,mCAMiB;AAEjB,oDAAuD;AACvD,yDAAuD;AACvD,oCAAyC;AACzC,SAAgB,2BAA2B,CACzC,UAAkB,EAClB,uBAAgD,EAChD,aAAyB,EAAE;IAE3B,MAAM,OAAO,GAAG,uBAAuB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7D,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,EAAE;QAC1C,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,0BAAkB,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE1F,IAAI,CAAC,UAAU,EAAE;YACf,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SAC7B;KACF;IAED,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE;QAClC,MAAM,kBAAkB,GAAG,IAAA,oCAAiB,EAAC,UAAU,CAAC,CAAC;QACzD,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,mCAAmB,EAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QACnF,IAAI,SAAS,KAAK,qBAAa,CAAC,IAAI,EAAE;YACpC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SAC7B;KACF;IAED,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,gCAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,gCAAwB,CAAC,eAAe;KAC/G,CAAC;AACJ,CAAC;AA3BD,kEA2BC;AAED,SAAgB,+BAA+B,CAC7C,aAAqB,EACrB,uBAAgD,EAChD,UAAuB;IAEvB,MAAM,UAAU,GAAG,uBAAuB,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IAEtE,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,gCAAwB,CAAC,kBAAkB,EAAE,CAAC;KAC1F;IAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,aAAa,EAAE,uBAAuB,CAAC,CAAC;IAEjF,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;QAC1B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;KAC7B;IAED,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,KAAK,MAAM,UAAU,IAAI,cAAc,EAAE;QACvC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,2BAA2B,CAAC,UAAU,EAAE,uBAAuB,EAAE,UAAU,CAAC,CAAC;QAEnH,IAAI,UAAU,EAAE;YACd,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SAC7B;QAED,IAAI,aAAa,KAAK,gCAAwB,CAAC,cAAc,EAAE;YAC7D,UAAU,GAAG,IAAI,CAAC;SACnB;KACF;IAED,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,gCAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,gCAAwB,CAAC,eAAe;KAC/G,CAAC;AACJ,CAAC;AAnCD,0EAmCC;AAED,SAAS,iBAAiB,CAAC,aAAqB,EAAE,uBAAgD;IAChG,OAAO,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CACzE,uBAAuB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,aAAa,CAAC,CACvF,CAAC;AACJ,CAAC"}
|
|
@@ -21,11 +21,11 @@ export type FronteggAttributes = {
|
|
|
21
21
|
tenantId?: string;
|
|
22
22
|
userId?: string;
|
|
23
23
|
email?: string;
|
|
24
|
-
|
|
25
|
-
[unmappedAttribute: string]: unknown;
|
|
24
|
+
emailVerified?: boolean;
|
|
26
25
|
};
|
|
27
26
|
export type Attributes = {
|
|
28
27
|
custom?: CustomAttributes;
|
|
29
|
-
|
|
28
|
+
jwt?: JwtAttributes;
|
|
30
29
|
};
|
|
30
|
+
export type JwtAttributes = Record<string, unknown>;
|
|
31
31
|
export declare const NO_EXPIRATION_TIME = -1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/user-entitlements/types.ts"],"names":[],"mappings":";;;AAkBA,IAAY,wBAIX;AAJD,WAAY,wBAAwB;IAClC,+DAAmC,CAAA;IACnC,qEAAyC,CAAA;IACzC,6DAAiC,CAAA;AACnC,CAAC,EAJW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAInC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/user-entitlements/types.ts"],"names":[],"mappings":";;;AAkBA,IAAY,wBAIX;AAJD,WAAY,wBAAwB;IAClC,+DAAmC,CAAA;IACnC,qEAAyC,CAAA;IACzC,6DAAiC,CAAA;AACnC,CAAC,EAJW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAInC;AAaY,QAAA,kBAAkB,GAAG,CAAC,CAAC,CAAC"}
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.0.0-alpha.12](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.0.0-alpha.11...v-1.0.0-alpha.12) (2023-10-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **string:** fix string sanitizers type to match opertaions ([#21](https://github.com/frontegg/entitlements-javascript-commons/issues/21)) ([4461155](https://github.com/frontegg/entitlements-javascript-commons/commit/4461155e53c0ef6f647ff4bc0215804667b52928))
|
|
7
|
+
|
|
8
|
+
# [1.0.0-alpha.11](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.0.0-alpha.10...v-1.0.0-alpha.11) (2023-10-17)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **user-entitlements:** handle jwt attributes ([cc0ce70](https://github.com/frontegg/entitlements-javascript-commons/commit/cc0ce70f4c3ebf2b3b410865d740c23ab1d0d9ed))
|
|
14
|
+
|
|
1
15
|
# [1.0.0-alpha.10](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.0.0-alpha.9...v-1.0.0-alpha.10) (2023-10-12)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontegg/entitlements-javascript-commons",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.12",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@fast-check/jest": "^1.7.3",
|
|
26
26
|
"@semantic-release/changelog": "^6.0.1",
|
|
27
27
|
"@semantic-release/git": "^10.0.1",
|
|
28
|
+
"@types/flat": "^5.0.3",
|
|
28
29
|
"@types/jest": "^29.2.0",
|
|
29
30
|
"@types/sinon": "^10.0.15",
|
|
30
31
|
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
|
@@ -39,5 +40,8 @@
|
|
|
39
40
|
"sinon": "^15.2.0",
|
|
40
41
|
"ts-jest": "^28.0.8",
|
|
41
42
|
"typescript": "^4.8.4"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"flat": "^5.0.2"
|
|
42
46
|
}
|
|
43
47
|
}
|
package/src/index.ts
CHANGED
|
@@ -27,7 +27,7 @@ export const sanitizeListString: Sanitizer<ListStringOperationPayload> = (value)
|
|
|
27
27
|
export const StringSanitizersMapper: SanitizersMapper<StringOperationPayload> = {
|
|
28
28
|
[OperationEnum.Matches]: sanitizeSingleString,
|
|
29
29
|
[OperationEnum.Contains]: sanitizeListString,
|
|
30
|
-
[OperationEnum.StartsWith]:
|
|
31
|
-
[OperationEnum.EndsWith]:
|
|
30
|
+
[OperationEnum.StartsWith]: sanitizeListString,
|
|
31
|
+
[OperationEnum.EndsWith]: sanitizeListString,
|
|
32
32
|
[OperationEnum.InList]: sanitizeListString,
|
|
33
33
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { flatten } from 'flat';
|
|
2
|
+
import { Attributes, JwtAttributes, FronteggAttributes } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Merges both `custom` and `jwt` records, map Frontegg attributes and modifies record keys with corrisponding prefixes
|
|
6
|
+
*
|
|
7
|
+
* Example:
|
|
8
|
+
* Input: { 'custom': { 'customAttribute': 'someValue' }, 'jwt': { 'email': 'user@email.com', other: 'some-vaule' } }
|
|
9
|
+
* Output: { 'customAttribute': 'someValue', 'frontegg.email': 'user@email.com', 'jwt.email': 'user@email.com', 'jwt.other': 'some-vaule' }
|
|
10
|
+
*/
|
|
11
|
+
export function prepareAttributes(
|
|
12
|
+
attributes: Attributes = {},
|
|
13
|
+
customFronteggAttributesMapper?: (jwtAttributes: JwtAttributes) => FronteggAttributes,
|
|
14
|
+
): Record<string, unknown> {
|
|
15
|
+
const { custom = {}, jwt = {} } = attributes;
|
|
16
|
+
const flatJwtAttributes = flatten<JwtAttributes, JwtAttributes>(jwt);
|
|
17
|
+
const fronteggAttributes = customFronteggAttributesMapper
|
|
18
|
+
? customFronteggAttributesMapper(jwt)
|
|
19
|
+
: defaultFronteggAttributesMapper(jwt);
|
|
20
|
+
const fronteggAttributesPrefix = 'frontegg.';
|
|
21
|
+
const jwtAttributesPrefix = 'jwt.';
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
...custom,
|
|
25
|
+
...modifyObjectKeysWithPrefix(fronteggAttributes, fronteggAttributesPrefix),
|
|
26
|
+
...modifyObjectKeysWithPrefix(flatJwtAttributes, jwtAttributesPrefix),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function defaultFronteggAttributesMapper(jwt: JwtAttributes): FronteggAttributes {
|
|
31
|
+
return {
|
|
32
|
+
email: jwt.email as string,
|
|
33
|
+
emailVerified: jwt.email_verified as boolean,
|
|
34
|
+
tenantId: jwt.tenantId as string,
|
|
35
|
+
userId: jwt.userId as string,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function modifyObjectKeysWithPrefix(object: Record<string, unknown>, prefix: string): Record<string, unknown> {
|
|
40
|
+
return Object.keys(object).reduce((modifiedObject, currentKey) => {
|
|
41
|
+
modifiedObject[`${prefix}${currentKey}`] = object[currentKey];
|
|
42
|
+
return modifiedObject;
|
|
43
|
+
}, {});
|
|
44
|
+
}
|
|
@@ -5,12 +5,14 @@ import {
|
|
|
5
5
|
UserEntitlementsContext,
|
|
6
6
|
Attributes,
|
|
7
7
|
} from './types';
|
|
8
|
+
|
|
8
9
|
import { evaluateFeatureFlag } from '../feature-flags';
|
|
10
|
+
import { prepareAttributes } from './attributes.utils';
|
|
9
11
|
import { TreatmentEnum } from '../rules';
|
|
10
12
|
export function evaluateIsEntitledToFeature(
|
|
11
13
|
featureKey: string,
|
|
12
14
|
userEntitlementsContext: UserEntitlementsContext,
|
|
13
|
-
attributes
|
|
15
|
+
attributes: Attributes = {},
|
|
14
16
|
): EntitlementResult {
|
|
15
17
|
const feature = userEntitlementsContext.features[featureKey];
|
|
16
18
|
let hasExpired = false;
|
|
@@ -23,7 +25,8 @@ export function evaluateIsEntitledToFeature(
|
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
if (feature && feature.featureFlag) {
|
|
26
|
-
const
|
|
28
|
+
const preparedAttributes = prepareAttributes(attributes);
|
|
29
|
+
const { treatment } = evaluateFeatureFlag(feature.featureFlag, preparedAttributes);
|
|
27
30
|
if (treatment === TreatmentEnum.True) {
|
|
28
31
|
return { isEntitled: true };
|
|
29
32
|
}
|
|
@@ -77,23 +80,3 @@ function getLinkedFeatures(permissionKey: string, userEntitlementsContext: UserE
|
|
|
77
80
|
userEntitlementsContext.features[featureKey].linkedPermissions.includes(permissionKey),
|
|
78
81
|
);
|
|
79
82
|
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Merges the `custom` and `frontegg` Records into a single Record,
|
|
83
|
-
* Alters the `frontegg` Record keys with a prefix
|
|
84
|
-
* Example:
|
|
85
|
-
* Input: { 'custom': { 'customAttribute': 'someValue' }, 'frontegg': { 'email': 'user@email.com' } }
|
|
86
|
-
* Output: { 'customAttribute': 'someValue', 'imported.email': 'user@email.com' }
|
|
87
|
-
*/
|
|
88
|
-
export function prepareAttributes(attributes: Attributes = {}): Record<string, unknown> {
|
|
89
|
-
const { custom = {}, frontegg = {} } = attributes;
|
|
90
|
-
const importedAttributesPrefix = 'imported.'; // Not Final
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
...custom,
|
|
94
|
-
...Object.keys(frontegg).reduce((modifiedImportedAttributes, key) => {
|
|
95
|
-
modifiedImportedAttributes[`${importedAttributesPrefix}${key}`] = frontegg[key];
|
|
96
|
-
return modifiedImportedAttributes;
|
|
97
|
-
}, {}),
|
|
98
|
-
};
|
|
99
|
-
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as AttributesUtils from '../attributes.utils';
|
|
2
|
+
import { Attributes, FronteggAttributes, JwtAttributes } from '../types';
|
|
3
|
+
import { flatten } from 'flat';
|
|
4
|
+
describe('prepareAttributes', () => {
|
|
5
|
+
test('given custom & jwt attributes, expected is merged & flatten attributes record', () => {
|
|
6
|
+
const attributes: Attributes = {
|
|
7
|
+
custom: {
|
|
8
|
+
customAttribute: 'some-value',
|
|
9
|
+
},
|
|
10
|
+
jwt: {
|
|
11
|
+
userId: 'user-1',
|
|
12
|
+
tenantId: 'tenant-1',
|
|
13
|
+
email: 'test@email.com',
|
|
14
|
+
email_verified: true,
|
|
15
|
+
dummyAttribute: 'dummy',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const expectedPreparedAttributes = {
|
|
20
|
+
customAttribute: 'some-value',
|
|
21
|
+
'frontegg.userId': 'user-1',
|
|
22
|
+
'frontegg.tenantId': 'tenant-1',
|
|
23
|
+
'frontegg.email': 'test@email.com',
|
|
24
|
+
'frontegg.emailVerified': true,
|
|
25
|
+
'jwt.userId': 'user-1',
|
|
26
|
+
'jwt.tenantId': 'tenant-1',
|
|
27
|
+
'jwt.email': 'test@email.com',
|
|
28
|
+
'jwt.email_verified': true,
|
|
29
|
+
'jwt.dummyAttribute': 'dummy',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const preparedAttributes = AttributesUtils.prepareAttributes(attributes);
|
|
33
|
+
|
|
34
|
+
expect(preparedAttributes).toEqual(expectedPreparedAttributes);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('defaultFronteggAttributesMapper', () => {
|
|
39
|
+
test('given jwt-attributes, expected mapped frontegg-attributes', async () => {
|
|
40
|
+
const jwtAttributes: JwtAttributes = {
|
|
41
|
+
userId: 'user-1',
|
|
42
|
+
tenantId: 'tenant-1',
|
|
43
|
+
email: 'test@email.com',
|
|
44
|
+
email_verified: true,
|
|
45
|
+
dummyAttribute: 'dummy',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const expectedFronteggAttributes: FronteggAttributes = {
|
|
49
|
+
userId: 'user-1',
|
|
50
|
+
tenantId: 'tenant-1',
|
|
51
|
+
email: 'test@email.com',
|
|
52
|
+
emailVerified: true,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const mappedAttributes = AttributesUtils.defaultFronteggAttributesMapper(jwtAttributes);
|
|
56
|
+
|
|
57
|
+
expect(mappedAttributes).toEqual(expectedFronteggAttributes);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('modifyObjectKeysWithPrefix', () => {
|
|
62
|
+
test('given object and prefix, object keys should altered with prefix', async () => {
|
|
63
|
+
const prefix = 'test.';
|
|
64
|
+
const obj = {
|
|
65
|
+
property: 'value',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const expectedModifiedObject = {
|
|
69
|
+
'test.property': 'value',
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const modifiedObject = AttributesUtils.modifyObjectKeysWithPrefix(obj, prefix);
|
|
73
|
+
|
|
74
|
+
expect(modifiedObject).toEqual(expectedModifiedObject);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import * as FeatureFlags from '../../feature-flags/feature-flag.evaluator';
|
|
2
1
|
import * as IsEntitledEvaluators from '../is-entitled.evaluator';
|
|
2
|
+
import * as FeatureFlagEvalutor from '../../feature-flags/feature-flag.evaluator';
|
|
3
|
+
import * as AttributesUtils from '../attributes.utils';
|
|
3
4
|
import { TreatmentEnum } from '../../rules';
|
|
4
|
-
import {
|
|
5
|
-
EntitlementResult,
|
|
6
|
-
NotEntitledJustification,
|
|
7
|
-
NO_EXPIRATION_TIME,
|
|
8
|
-
UserEntitlementsContext,
|
|
9
|
-
Attributes,
|
|
10
|
-
} from '../types';
|
|
5
|
+
import { EntitlementResult, NotEntitledJustification, NO_EXPIRATION_TIME, UserEntitlementsContext } from '../types';
|
|
11
6
|
import { FeatureFlag } from '../../feature-flags/types';
|
|
7
|
+
|
|
12
8
|
const mockFeatureFlag: FeatureFlag = {
|
|
13
9
|
on: true,
|
|
14
10
|
defaultTreatment: TreatmentEnum.True,
|
|
@@ -31,10 +27,13 @@ const falsyEntitlementResultMissingPermission: EntitlementResult = {
|
|
|
31
27
|
justification: NotEntitledJustification.MISSING_PERMISSION,
|
|
32
28
|
};
|
|
33
29
|
describe('evaluateIsEntitledToFeature', () => {
|
|
30
|
+
beforeAll(() => {
|
|
31
|
+
jest.spyOn(AttributesUtils, 'prepareAttributes').mockReturnValue({ testAttribute: 'test-value' });
|
|
32
|
+
});
|
|
34
33
|
describe('entitled', () => {
|
|
35
34
|
describe('feature-flag evaluated truthy', () => {
|
|
36
35
|
beforeAll(async () => {
|
|
37
|
-
jest.spyOn(
|
|
36
|
+
jest.spyOn(FeatureFlagEvalutor, 'evaluateFeatureFlag').mockReturnValue({ treatment: TreatmentEnum.True });
|
|
38
37
|
});
|
|
39
38
|
|
|
40
39
|
test('feature granted with valid expiration date', async () => {
|
|
@@ -100,7 +99,7 @@ describe('evaluateIsEntitledToFeature', () => {
|
|
|
100
99
|
});
|
|
101
100
|
describe('feature-flag evaluated falsy', () => {
|
|
102
101
|
beforeAll(async () => {
|
|
103
|
-
jest.spyOn(
|
|
102
|
+
jest.spyOn(FeatureFlagEvalutor, 'evaluateFeatureFlag').mockReturnValue({ treatment: TreatmentEnum.False });
|
|
104
103
|
});
|
|
105
104
|
test('feature granted with no expiration date', async () => {
|
|
106
105
|
const userEntitlementContext: UserEntitlementsContext = {
|
|
@@ -168,7 +167,7 @@ describe('evaluateIsEntitledToFeature', () => {
|
|
|
168
167
|
describe('not entitled', () => {
|
|
169
168
|
describe('feature-flag evaluated falsy', () => {
|
|
170
169
|
beforeAll(async () => {
|
|
171
|
-
jest.spyOn(
|
|
170
|
+
jest.spyOn(FeatureFlagEvalutor, 'evaluateFeatureFlag').mockReturnValue({ treatment: TreatmentEnum.False });
|
|
172
171
|
});
|
|
173
172
|
test('feature has not been granted', async () => {
|
|
174
173
|
const userEntitlementContext: UserEntitlementsContext = {
|
|
@@ -176,6 +175,7 @@ describe('evaluateIsEntitledToFeature', () => {
|
|
|
176
175
|
'test-feature': {
|
|
177
176
|
expireTime: null,
|
|
178
177
|
linkedPermissions: [],
|
|
178
|
+
featureFlag: mockFeatureFlag,
|
|
179
179
|
},
|
|
180
180
|
},
|
|
181
181
|
permissions: {},
|
|
@@ -190,6 +190,7 @@ describe('evaluateIsEntitledToFeature', () => {
|
|
|
190
190
|
'test-feature': {
|
|
191
191
|
expireTime: Date.now() - 3600,
|
|
192
192
|
linkedPermissions: [],
|
|
193
|
+
featureFlag: mockFeatureFlag,
|
|
193
194
|
},
|
|
194
195
|
},
|
|
195
196
|
permissions: {},
|
|
@@ -295,21 +296,3 @@ describe('evaluateIsEntitledToPermission', () => {
|
|
|
295
296
|
expect(result).toEqual(falsyEntitlementResultBundleExpired);
|
|
296
297
|
});
|
|
297
298
|
});
|
|
298
|
-
|
|
299
|
-
describe('prepareAttributes', () => {
|
|
300
|
-
test('given custom & frontegg attributes, expected is merged Record, frontegg attributes altered with prefix', async () => {
|
|
301
|
-
const attributes: Attributes = {
|
|
302
|
-
custom: { testAttribute: 'testValue' },
|
|
303
|
-
frontegg: { email: 'test@email.com', unknownFronteggAttribute: 'unknownFronteggAttribute' },
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
const expectedPreparedAttributes: Record<string, unknown> = {
|
|
307
|
-
testAttribute: 'testValue',
|
|
308
|
-
'imported.email': 'test@email.com',
|
|
309
|
-
'imported.unknownFronteggAttribute': 'unknownFronteggAttribute',
|
|
310
|
-
};
|
|
311
|
-
const preparedAttributes = IsEntitledEvaluators.prepareAttributes(attributes);
|
|
312
|
-
|
|
313
|
-
expect(preparedAttributes).toEqual(expectedPreparedAttributes);
|
|
314
|
-
});
|
|
315
|
-
});
|
|
@@ -28,10 +28,9 @@ export type FronteggAttributes = {
|
|
|
28
28
|
tenantId?: string;
|
|
29
29
|
userId?: string;
|
|
30
30
|
email?: string;
|
|
31
|
-
|
|
32
|
-
[unmappedAttribute: string]: unknown;
|
|
31
|
+
emailVerified?: boolean;
|
|
33
32
|
};
|
|
34
33
|
|
|
35
|
-
export type Attributes = { custom?: CustomAttributes;
|
|
36
|
-
|
|
34
|
+
export type Attributes = { custom?: CustomAttributes; jwt?: JwtAttributes };
|
|
35
|
+
export type JwtAttributes = Record<string, unknown>;
|
|
37
36
|
export const NO_EXPIRATION_TIME = -1;
|