@naylence/runtime 0.4.3 → 0.4.4
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/browser/index.cjs +66 -20
- package/dist/browser/index.mjs +66 -20
- package/dist/cjs/naylence/fame/security/auth/policy/basic-authorization-policy.js +54 -14
- package/dist/cjs/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js +10 -4
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/security/auth/policy/basic-authorization-policy.js +54 -14
- package/dist/esm/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js +10 -4
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +66 -20
- package/dist/node/index.mjs +66 -20
- package/dist/node/node.cjs +66 -20
- package/dist/node/node.mjs +66 -20
- package/dist/types/naylence/fame/security/auth/policy/authorization-policy-definition.d.ts +8 -2
- package/dist/types/naylence/fame/security/auth/policy/basic-authorization-policy.d.ts +2 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/browser/index.cjs
CHANGED
|
@@ -525,12 +525,12 @@ async function ensureRuntimeFactoriesRegistered(registry = factory.Registry) {
|
|
|
525
525
|
}
|
|
526
526
|
|
|
527
527
|
// This file is auto-generated during build - do not edit manually
|
|
528
|
-
// Generated from package.json version: 0.4.
|
|
528
|
+
// Generated from package.json version: 0.4.4
|
|
529
529
|
/**
|
|
530
530
|
* The package version, injected at build time.
|
|
531
531
|
* @internal
|
|
532
532
|
*/
|
|
533
|
-
const VERSION = '0.4.
|
|
533
|
+
const VERSION = '0.4.4';
|
|
534
534
|
|
|
535
535
|
let initialized = false;
|
|
536
536
|
const runtimePlugin = {
|
|
@@ -22676,6 +22676,7 @@ class BasicAuthorizationPolicy {
|
|
|
22676
22676
|
// Action must be explicitly provided; default to wildcard if omitted
|
|
22677
22677
|
// for backward compatibility during transition
|
|
22678
22678
|
const resolvedAction = action ?? '*';
|
|
22679
|
+
const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
|
|
22679
22680
|
const address = extractAddress(envelope);
|
|
22680
22681
|
const grantedScopes = extractGrantedScopes(context);
|
|
22681
22682
|
const rawFrameType = envelope.frame
|
|
@@ -22685,8 +22686,8 @@ class BasicAuthorizationPolicy {
|
|
|
22685
22686
|
: '';
|
|
22686
22687
|
// Extract and normalize origin type for rule matching
|
|
22687
22688
|
const rawOriginType = context?.originType;
|
|
22688
|
-
const originTypeNormalized = typeof rawOriginType === 'string'
|
|
22689
|
-
?
|
|
22689
|
+
const originTypeNormalized = typeof rawOriginType === 'string'
|
|
22690
|
+
? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
|
|
22690
22691
|
: undefined;
|
|
22691
22692
|
const evaluationTrace = [];
|
|
22692
22693
|
// Evaluate rules in order (first match wins)
|
|
@@ -22733,8 +22734,8 @@ class BasicAuthorizationPolicy {
|
|
|
22733
22734
|
}
|
|
22734
22735
|
}
|
|
22735
22736
|
// Check action match
|
|
22736
|
-
if (!rule.actions.has('*') && !rule.actions.has(
|
|
22737
|
-
step.expression = `action: ${
|
|
22737
|
+
if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
|
|
22738
|
+
step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
|
|
22738
22739
|
step.result = false;
|
|
22739
22740
|
evaluationTrace.push(step);
|
|
22740
22741
|
continue;
|
|
@@ -22801,6 +22802,9 @@ class BasicAuthorizationPolicy {
|
|
|
22801
22802
|
};
|
|
22802
22803
|
}
|
|
22803
22804
|
validateDefaultEffect(effect) {
|
|
22805
|
+
if (effect === undefined || effect === null) {
|
|
22806
|
+
return 'deny';
|
|
22807
|
+
}
|
|
22804
22808
|
if (effect !== 'allow' && effect !== 'deny') {
|
|
22805
22809
|
throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
|
|
22806
22810
|
}
|
|
@@ -22873,10 +22877,11 @@ class BasicAuthorizationPolicy {
|
|
|
22873
22877
|
}
|
|
22874
22878
|
// Handle single action
|
|
22875
22879
|
if (typeof action === 'string') {
|
|
22876
|
-
|
|
22880
|
+
const normalized = this.normalizeActionToken(action);
|
|
22881
|
+
if (!normalized) {
|
|
22877
22882
|
throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
|
|
22878
22883
|
}
|
|
22879
|
-
return new Set([
|
|
22884
|
+
return new Set([normalized]);
|
|
22880
22885
|
}
|
|
22881
22886
|
// Handle array of actions
|
|
22882
22887
|
if (!Array.isArray(action)) {
|
|
@@ -22890,10 +22895,11 @@ class BasicAuthorizationPolicy {
|
|
|
22890
22895
|
if (typeof a !== 'string') {
|
|
22891
22896
|
throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
|
|
22892
22897
|
}
|
|
22893
|
-
|
|
22898
|
+
const normalized = this.normalizeActionToken(a);
|
|
22899
|
+
if (!normalized) {
|
|
22894
22900
|
throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
|
|
22895
22901
|
}
|
|
22896
|
-
actions.add(
|
|
22902
|
+
actions.add(normalized);
|
|
22897
22903
|
}
|
|
22898
22904
|
return actions;
|
|
22899
22905
|
}
|
|
@@ -22996,11 +23002,12 @@ class BasicAuthorizationPolicy {
|
|
|
22996
23002
|
}
|
|
22997
23003
|
// Handle single origin type
|
|
22998
23004
|
if (typeof originType === 'string') {
|
|
22999
|
-
const
|
|
23000
|
-
if (!
|
|
23005
|
+
const trimmed = originType.trim();
|
|
23006
|
+
if (!trimmed) {
|
|
23001
23007
|
throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
|
|
23002
23008
|
}
|
|
23003
|
-
|
|
23009
|
+
const normalized = this.normalizeOriginTypeToken(trimmed);
|
|
23010
|
+
if (!normalized) {
|
|
23004
23011
|
throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
|
|
23005
23012
|
}
|
|
23006
23013
|
return new Set([normalized]);
|
|
@@ -23017,17 +23024,50 @@ class BasicAuthorizationPolicy {
|
|
|
23017
23024
|
if (typeof ot !== 'string') {
|
|
23018
23025
|
throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
|
|
23019
23026
|
}
|
|
23020
|
-
const
|
|
23021
|
-
if (!
|
|
23027
|
+
const trimmed = ot.trim();
|
|
23028
|
+
if (!trimmed) {
|
|
23022
23029
|
throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
|
|
23023
23030
|
}
|
|
23024
|
-
|
|
23031
|
+
const normalized = this.normalizeOriginTypeToken(trimmed);
|
|
23032
|
+
if (!normalized) {
|
|
23025
23033
|
throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
|
|
23026
23034
|
}
|
|
23027
23035
|
originTypes.add(normalized);
|
|
23028
23036
|
}
|
|
23029
23037
|
return originTypes;
|
|
23030
23038
|
}
|
|
23039
|
+
normalizeActionToken(value) {
|
|
23040
|
+
const trimmed = value.trim();
|
|
23041
|
+
if (!trimmed) {
|
|
23042
|
+
return null;
|
|
23043
|
+
}
|
|
23044
|
+
if (trimmed === '*') {
|
|
23045
|
+
return '*';
|
|
23046
|
+
}
|
|
23047
|
+
const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
|
|
23048
|
+
const map = {
|
|
23049
|
+
connect: 'Connect',
|
|
23050
|
+
forwardupstream: 'ForwardUpstream',
|
|
23051
|
+
forwarddownstream: 'ForwardDownstream',
|
|
23052
|
+
forwardpeer: 'ForwardPeer',
|
|
23053
|
+
deliverlocal: 'DeliverLocal',
|
|
23054
|
+
};
|
|
23055
|
+
return map[normalized] ?? null;
|
|
23056
|
+
}
|
|
23057
|
+
normalizeOriginTypeToken(value) {
|
|
23058
|
+
const trimmed = value.trim();
|
|
23059
|
+
if (!trimmed) {
|
|
23060
|
+
return null;
|
|
23061
|
+
}
|
|
23062
|
+
const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
|
|
23063
|
+
const map = {
|
|
23064
|
+
downstream: 'downstream',
|
|
23065
|
+
upstream: 'upstream',
|
|
23066
|
+
peer: 'peer',
|
|
23067
|
+
local: 'local',
|
|
23068
|
+
};
|
|
23069
|
+
return map[normalized] ?? null;
|
|
23070
|
+
}
|
|
23031
23071
|
}
|
|
23032
23072
|
|
|
23033
23073
|
var basicAuthorizationPolicy = /*#__PURE__*/Object.freeze({
|
|
@@ -42776,16 +42816,22 @@ class LocalFileAuthorizationPolicySource {
|
|
|
42776
42816
|
const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
|
|
42777
42817
|
// Ensure we have a type field for the factory
|
|
42778
42818
|
if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
|
|
42779
|
-
|
|
42780
|
-
|
|
42819
|
+
logger$1.warning('policy_type_missing_defaulting_to_basic', {
|
|
42820
|
+
path: this.path,
|
|
42821
|
+
});
|
|
42822
|
+
factoryConfig.type =
|
|
42823
|
+
'BasicAuthorizationPolicy';
|
|
42781
42824
|
}
|
|
42782
42825
|
// Build the factory config with the policy definition
|
|
42783
42826
|
// The file content IS the policy definition, so we extract the type
|
|
42784
42827
|
// and wrap the remaining content as the policyDefinition
|
|
42785
|
-
const { type, ...restOfFile } = policyDefinition;
|
|
42828
|
+
const { type: fileType, ...restOfFile } = policyDefinition;
|
|
42829
|
+
const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
|
|
42830
|
+
? fileType
|
|
42831
|
+
: factoryConfig.type;
|
|
42786
42832
|
const mergedConfig = this.policyFactoryConfig != null
|
|
42787
42833
|
? { ...this.policyFactoryConfig, policyDefinition }
|
|
42788
|
-
: { type:
|
|
42834
|
+
: { type: resolvedType, policyDefinition: restOfFile };
|
|
42789
42835
|
// Create the policy using the factory system
|
|
42790
42836
|
const policy = await AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
|
|
42791
42837
|
if (!policy) {
|
package/dist/browser/index.mjs
CHANGED
|
@@ -523,12 +523,12 @@ async function ensureRuntimeFactoriesRegistered(registry = Registry) {
|
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
// This file is auto-generated during build - do not edit manually
|
|
526
|
-
// Generated from package.json version: 0.4.
|
|
526
|
+
// Generated from package.json version: 0.4.4
|
|
527
527
|
/**
|
|
528
528
|
* The package version, injected at build time.
|
|
529
529
|
* @internal
|
|
530
530
|
*/
|
|
531
|
-
const VERSION = '0.4.
|
|
531
|
+
const VERSION = '0.4.4';
|
|
532
532
|
|
|
533
533
|
let initialized = false;
|
|
534
534
|
const runtimePlugin = {
|
|
@@ -22674,6 +22674,7 @@ class BasicAuthorizationPolicy {
|
|
|
22674
22674
|
// Action must be explicitly provided; default to wildcard if omitted
|
|
22675
22675
|
// for backward compatibility during transition
|
|
22676
22676
|
const resolvedAction = action ?? '*';
|
|
22677
|
+
const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
|
|
22677
22678
|
const address = extractAddress(envelope);
|
|
22678
22679
|
const grantedScopes = extractGrantedScopes(context);
|
|
22679
22680
|
const rawFrameType = envelope.frame
|
|
@@ -22683,8 +22684,8 @@ class BasicAuthorizationPolicy {
|
|
|
22683
22684
|
: '';
|
|
22684
22685
|
// Extract and normalize origin type for rule matching
|
|
22685
22686
|
const rawOriginType = context?.originType;
|
|
22686
|
-
const originTypeNormalized = typeof rawOriginType === 'string'
|
|
22687
|
-
?
|
|
22687
|
+
const originTypeNormalized = typeof rawOriginType === 'string'
|
|
22688
|
+
? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
|
|
22688
22689
|
: undefined;
|
|
22689
22690
|
const evaluationTrace = [];
|
|
22690
22691
|
// Evaluate rules in order (first match wins)
|
|
@@ -22731,8 +22732,8 @@ class BasicAuthorizationPolicy {
|
|
|
22731
22732
|
}
|
|
22732
22733
|
}
|
|
22733
22734
|
// Check action match
|
|
22734
|
-
if (!rule.actions.has('*') && !rule.actions.has(
|
|
22735
|
-
step.expression = `action: ${
|
|
22735
|
+
if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
|
|
22736
|
+
step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
|
|
22736
22737
|
step.result = false;
|
|
22737
22738
|
evaluationTrace.push(step);
|
|
22738
22739
|
continue;
|
|
@@ -22799,6 +22800,9 @@ class BasicAuthorizationPolicy {
|
|
|
22799
22800
|
};
|
|
22800
22801
|
}
|
|
22801
22802
|
validateDefaultEffect(effect) {
|
|
22803
|
+
if (effect === undefined || effect === null) {
|
|
22804
|
+
return 'deny';
|
|
22805
|
+
}
|
|
22802
22806
|
if (effect !== 'allow' && effect !== 'deny') {
|
|
22803
22807
|
throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
|
|
22804
22808
|
}
|
|
@@ -22871,10 +22875,11 @@ class BasicAuthorizationPolicy {
|
|
|
22871
22875
|
}
|
|
22872
22876
|
// Handle single action
|
|
22873
22877
|
if (typeof action === 'string') {
|
|
22874
|
-
|
|
22878
|
+
const normalized = this.normalizeActionToken(action);
|
|
22879
|
+
if (!normalized) {
|
|
22875
22880
|
throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
|
|
22876
22881
|
}
|
|
22877
|
-
return new Set([
|
|
22882
|
+
return new Set([normalized]);
|
|
22878
22883
|
}
|
|
22879
22884
|
// Handle array of actions
|
|
22880
22885
|
if (!Array.isArray(action)) {
|
|
@@ -22888,10 +22893,11 @@ class BasicAuthorizationPolicy {
|
|
|
22888
22893
|
if (typeof a !== 'string') {
|
|
22889
22894
|
throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
|
|
22890
22895
|
}
|
|
22891
|
-
|
|
22896
|
+
const normalized = this.normalizeActionToken(a);
|
|
22897
|
+
if (!normalized) {
|
|
22892
22898
|
throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
|
|
22893
22899
|
}
|
|
22894
|
-
actions.add(
|
|
22900
|
+
actions.add(normalized);
|
|
22895
22901
|
}
|
|
22896
22902
|
return actions;
|
|
22897
22903
|
}
|
|
@@ -22994,11 +23000,12 @@ class BasicAuthorizationPolicy {
|
|
|
22994
23000
|
}
|
|
22995
23001
|
// Handle single origin type
|
|
22996
23002
|
if (typeof originType === 'string') {
|
|
22997
|
-
const
|
|
22998
|
-
if (!
|
|
23003
|
+
const trimmed = originType.trim();
|
|
23004
|
+
if (!trimmed) {
|
|
22999
23005
|
throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
|
|
23000
23006
|
}
|
|
23001
|
-
|
|
23007
|
+
const normalized = this.normalizeOriginTypeToken(trimmed);
|
|
23008
|
+
if (!normalized) {
|
|
23002
23009
|
throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
|
|
23003
23010
|
}
|
|
23004
23011
|
return new Set([normalized]);
|
|
@@ -23015,17 +23022,50 @@ class BasicAuthorizationPolicy {
|
|
|
23015
23022
|
if (typeof ot !== 'string') {
|
|
23016
23023
|
throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
|
|
23017
23024
|
}
|
|
23018
|
-
const
|
|
23019
|
-
if (!
|
|
23025
|
+
const trimmed = ot.trim();
|
|
23026
|
+
if (!trimmed) {
|
|
23020
23027
|
throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
|
|
23021
23028
|
}
|
|
23022
|
-
|
|
23029
|
+
const normalized = this.normalizeOriginTypeToken(trimmed);
|
|
23030
|
+
if (!normalized) {
|
|
23023
23031
|
throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
|
|
23024
23032
|
}
|
|
23025
23033
|
originTypes.add(normalized);
|
|
23026
23034
|
}
|
|
23027
23035
|
return originTypes;
|
|
23028
23036
|
}
|
|
23037
|
+
normalizeActionToken(value) {
|
|
23038
|
+
const trimmed = value.trim();
|
|
23039
|
+
if (!trimmed) {
|
|
23040
|
+
return null;
|
|
23041
|
+
}
|
|
23042
|
+
if (trimmed === '*') {
|
|
23043
|
+
return '*';
|
|
23044
|
+
}
|
|
23045
|
+
const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
|
|
23046
|
+
const map = {
|
|
23047
|
+
connect: 'Connect',
|
|
23048
|
+
forwardupstream: 'ForwardUpstream',
|
|
23049
|
+
forwarddownstream: 'ForwardDownstream',
|
|
23050
|
+
forwardpeer: 'ForwardPeer',
|
|
23051
|
+
deliverlocal: 'DeliverLocal',
|
|
23052
|
+
};
|
|
23053
|
+
return map[normalized] ?? null;
|
|
23054
|
+
}
|
|
23055
|
+
normalizeOriginTypeToken(value) {
|
|
23056
|
+
const trimmed = value.trim();
|
|
23057
|
+
if (!trimmed) {
|
|
23058
|
+
return null;
|
|
23059
|
+
}
|
|
23060
|
+
const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
|
|
23061
|
+
const map = {
|
|
23062
|
+
downstream: 'downstream',
|
|
23063
|
+
upstream: 'upstream',
|
|
23064
|
+
peer: 'peer',
|
|
23065
|
+
local: 'local',
|
|
23066
|
+
};
|
|
23067
|
+
return map[normalized] ?? null;
|
|
23068
|
+
}
|
|
23029
23069
|
}
|
|
23030
23070
|
|
|
23031
23071
|
var basicAuthorizationPolicy = /*#__PURE__*/Object.freeze({
|
|
@@ -42774,16 +42814,22 @@ class LocalFileAuthorizationPolicySource {
|
|
|
42774
42814
|
const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
|
|
42775
42815
|
// Ensure we have a type field for the factory
|
|
42776
42816
|
if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
|
|
42777
|
-
|
|
42778
|
-
|
|
42817
|
+
logger$1.warning('policy_type_missing_defaulting_to_basic', {
|
|
42818
|
+
path: this.path,
|
|
42819
|
+
});
|
|
42820
|
+
factoryConfig.type =
|
|
42821
|
+
'BasicAuthorizationPolicy';
|
|
42779
42822
|
}
|
|
42780
42823
|
// Build the factory config with the policy definition
|
|
42781
42824
|
// The file content IS the policy definition, so we extract the type
|
|
42782
42825
|
// and wrap the remaining content as the policyDefinition
|
|
42783
|
-
const { type, ...restOfFile } = policyDefinition;
|
|
42826
|
+
const { type: fileType, ...restOfFile } = policyDefinition;
|
|
42827
|
+
const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
|
|
42828
|
+
? fileType
|
|
42829
|
+
: factoryConfig.type;
|
|
42784
42830
|
const mergedConfig = this.policyFactoryConfig != null
|
|
42785
42831
|
? { ...this.policyFactoryConfig, policyDefinition }
|
|
42786
|
-
: { type:
|
|
42832
|
+
: { type: resolvedType, policyDefinition: restOfFile };
|
|
42787
42833
|
// Create the policy using the factory system
|
|
42788
42834
|
const policy = await AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
|
|
42789
42835
|
if (!policy) {
|
|
@@ -93,6 +93,7 @@ class BasicAuthorizationPolicy {
|
|
|
93
93
|
// Action must be explicitly provided; default to wildcard if omitted
|
|
94
94
|
// for backward compatibility during transition
|
|
95
95
|
const resolvedAction = action ?? '*';
|
|
96
|
+
const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
|
|
96
97
|
const address = extractAddress(envelope);
|
|
97
98
|
const grantedScopes = extractGrantedScopes(context);
|
|
98
99
|
const rawFrameType = envelope.frame
|
|
@@ -102,8 +103,8 @@ class BasicAuthorizationPolicy {
|
|
|
102
103
|
: '';
|
|
103
104
|
// Extract and normalize origin type for rule matching
|
|
104
105
|
const rawOriginType = context?.originType;
|
|
105
|
-
const originTypeNormalized = typeof rawOriginType === 'string'
|
|
106
|
-
?
|
|
106
|
+
const originTypeNormalized = typeof rawOriginType === 'string'
|
|
107
|
+
? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
|
|
107
108
|
: undefined;
|
|
108
109
|
const evaluationTrace = [];
|
|
109
110
|
// Evaluate rules in order (first match wins)
|
|
@@ -150,8 +151,8 @@ class BasicAuthorizationPolicy {
|
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
// Check action match
|
|
153
|
-
if (!rule.actions.has('*') && !rule.actions.has(
|
|
154
|
-
step.expression = `action: ${
|
|
154
|
+
if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
|
|
155
|
+
step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
|
|
155
156
|
step.result = false;
|
|
156
157
|
evaluationTrace.push(step);
|
|
157
158
|
continue;
|
|
@@ -218,6 +219,9 @@ class BasicAuthorizationPolicy {
|
|
|
218
219
|
};
|
|
219
220
|
}
|
|
220
221
|
validateDefaultEffect(effect) {
|
|
222
|
+
if (effect === undefined || effect === null) {
|
|
223
|
+
return 'deny';
|
|
224
|
+
}
|
|
221
225
|
if (effect !== 'allow' && effect !== 'deny') {
|
|
222
226
|
throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
|
|
223
227
|
}
|
|
@@ -290,10 +294,11 @@ class BasicAuthorizationPolicy {
|
|
|
290
294
|
}
|
|
291
295
|
// Handle single action
|
|
292
296
|
if (typeof action === 'string') {
|
|
293
|
-
|
|
297
|
+
const normalized = this.normalizeActionToken(action);
|
|
298
|
+
if (!normalized) {
|
|
294
299
|
throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${authorization_policy_definition_js_1.VALID_ACTIONS.join(', ')}`);
|
|
295
300
|
}
|
|
296
|
-
return new Set([
|
|
301
|
+
return new Set([normalized]);
|
|
297
302
|
}
|
|
298
303
|
// Handle array of actions
|
|
299
304
|
if (!Array.isArray(action)) {
|
|
@@ -307,10 +312,11 @@ class BasicAuthorizationPolicy {
|
|
|
307
312
|
if (typeof a !== 'string') {
|
|
308
313
|
throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
|
|
309
314
|
}
|
|
310
|
-
|
|
315
|
+
const normalized = this.normalizeActionToken(a);
|
|
316
|
+
if (!normalized) {
|
|
311
317
|
throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${authorization_policy_definition_js_1.VALID_ACTIONS.join(', ')}`);
|
|
312
318
|
}
|
|
313
|
-
actions.add(
|
|
319
|
+
actions.add(normalized);
|
|
314
320
|
}
|
|
315
321
|
return actions;
|
|
316
322
|
}
|
|
@@ -413,11 +419,12 @@ class BasicAuthorizationPolicy {
|
|
|
413
419
|
}
|
|
414
420
|
// Handle single origin type
|
|
415
421
|
if (typeof originType === 'string') {
|
|
416
|
-
const
|
|
417
|
-
if (!
|
|
422
|
+
const trimmed = originType.trim();
|
|
423
|
+
if (!trimmed) {
|
|
418
424
|
throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
|
|
419
425
|
}
|
|
420
|
-
|
|
426
|
+
const normalized = this.normalizeOriginTypeToken(trimmed);
|
|
427
|
+
if (!normalized) {
|
|
421
428
|
throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${authorization_policy_definition_js_1.VALID_ORIGIN_TYPES.join(', ')}`);
|
|
422
429
|
}
|
|
423
430
|
return new Set([normalized]);
|
|
@@ -434,16 +441,49 @@ class BasicAuthorizationPolicy {
|
|
|
434
441
|
if (typeof ot !== 'string') {
|
|
435
442
|
throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
|
|
436
443
|
}
|
|
437
|
-
const
|
|
438
|
-
if (!
|
|
444
|
+
const trimmed = ot.trim();
|
|
445
|
+
if (!trimmed) {
|
|
439
446
|
throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
|
|
440
447
|
}
|
|
441
|
-
|
|
448
|
+
const normalized = this.normalizeOriginTypeToken(trimmed);
|
|
449
|
+
if (!normalized) {
|
|
442
450
|
throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${authorization_policy_definition_js_1.VALID_ORIGIN_TYPES.join(', ')}`);
|
|
443
451
|
}
|
|
444
452
|
originTypes.add(normalized);
|
|
445
453
|
}
|
|
446
454
|
return originTypes;
|
|
447
455
|
}
|
|
456
|
+
normalizeActionToken(value) {
|
|
457
|
+
const trimmed = value.trim();
|
|
458
|
+
if (!trimmed) {
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
if (trimmed === '*') {
|
|
462
|
+
return '*';
|
|
463
|
+
}
|
|
464
|
+
const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
|
|
465
|
+
const map = {
|
|
466
|
+
connect: 'Connect',
|
|
467
|
+
forwardupstream: 'ForwardUpstream',
|
|
468
|
+
forwarddownstream: 'ForwardDownstream',
|
|
469
|
+
forwardpeer: 'ForwardPeer',
|
|
470
|
+
deliverlocal: 'DeliverLocal',
|
|
471
|
+
};
|
|
472
|
+
return map[normalized] ?? null;
|
|
473
|
+
}
|
|
474
|
+
normalizeOriginTypeToken(value) {
|
|
475
|
+
const trimmed = value.trim();
|
|
476
|
+
if (!trimmed) {
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
|
|
480
|
+
const map = {
|
|
481
|
+
downstream: 'downstream',
|
|
482
|
+
upstream: 'upstream',
|
|
483
|
+
peer: 'peer',
|
|
484
|
+
local: 'local',
|
|
485
|
+
};
|
|
486
|
+
return map[normalized] ?? null;
|
|
487
|
+
}
|
|
448
488
|
}
|
|
449
489
|
exports.BasicAuthorizationPolicy = BasicAuthorizationPolicy;
|
package/dist/cjs/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js
CHANGED
|
@@ -123,16 +123,22 @@ class LocalFileAuthorizationPolicySource {
|
|
|
123
123
|
const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
|
|
124
124
|
// Ensure we have a type field for the factory
|
|
125
125
|
if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
logger.warning('policy_type_missing_defaulting_to_basic', {
|
|
127
|
+
path: this.path,
|
|
128
|
+
});
|
|
129
|
+
factoryConfig.type =
|
|
130
|
+
'BasicAuthorizationPolicy';
|
|
128
131
|
}
|
|
129
132
|
// Build the factory config with the policy definition
|
|
130
133
|
// The file content IS the policy definition, so we extract the type
|
|
131
134
|
// and wrap the remaining content as the policyDefinition
|
|
132
|
-
const { type, ...restOfFile } = policyDefinition;
|
|
135
|
+
const { type: fileType, ...restOfFile } = policyDefinition;
|
|
136
|
+
const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
|
|
137
|
+
? fileType
|
|
138
|
+
: factoryConfig.type;
|
|
133
139
|
const mergedConfig = this.policyFactoryConfig != null
|
|
134
140
|
? { ...this.policyFactoryConfig, policyDefinition }
|
|
135
|
-
: { type:
|
|
141
|
+
: { type: resolvedType, policyDefinition: restOfFile };
|
|
136
142
|
// Create the policy using the factory system
|
|
137
143
|
const policy = await authorization_policy_factory_js_1.AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
|
|
138
144
|
if (!policy) {
|
package/dist/cjs/version.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// This file is auto-generated during build - do not edit manually
|
|
3
|
-
// Generated from package.json version: 0.4.
|
|
3
|
+
// Generated from package.json version: 0.4.4
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
5
|
exports.VERSION = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* The package version, injected at build time.
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
|
-
exports.VERSION = '0.4.
|
|
10
|
+
exports.VERSION = '0.4.4';
|