Skip to content

Commit

Permalink
fix(core): support Content-Security-Policy header script-src 's… (#2199)
Browse files Browse the repository at this point in the history
fix #2157
  • Loading branch information
aitboudad committed Apr 22, 2020
1 parent 7019161 commit 23edc3e
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
1 change: 0 additions & 1 deletion src/core/src/lib/components/formly.field.config.ts
Expand Up @@ -173,7 +173,6 @@ export interface FormlyFieldConfig {

export interface ExpressionPropertyCache {
expression: (model: any, formState: any, field: FormlyFieldConfigCache) => boolean;
expressionValueSetter: (value: any) => void;
expressionValue?: any;
}

Expand Down
Expand Up @@ -468,6 +468,22 @@ describe('FieldExpressionExtension', () => {
expect(fields[0].formControl.value).toEqual('test');
});
});

it('should throw error when assign to an undefined prop', () => {
const fields: FormlyFieldConfig[] = [
{
key: 'visibilityToggle',
type: 'input',
expressionProperties: {
'nested.prop': '"ddd"',
},
},
];
const model = {};

const buildForm = () => builder.buildForm(form, fields, model, options);
expect(buildForm).toThrowError(/\[Formly Error\] \[Expression "nested.prop"\] Cannot set property 'prop' of undefined/i);
});
});

describe('field changes', () => {
Expand Down
30 changes: 18 additions & 12 deletions src/core/src/lib/extensions/field-expression/field-expression.ts
@@ -1,6 +1,6 @@
import { FormlyFieldConfig, FormlyValueChangeEvent, FormlyFieldConfigCache } from '../../components/formly.field.config';
import { isObject, isNullOrUndefined, isFunction, defineHiddenProp, wrapProperty, reduceFormUpdateValidityCalls } from '../../utils';
import { evalExpression, evalStringExpression, evalExpressionValueSetter } from './utils';
import { evalExpression, evalStringExpression } from './utils';
import { Observable } from 'rxjs';
import { FormlyExtension } from '../../services/formly.config';
import { unregisterControl, registerControl, updateValidity } from '../field-form/utils';
Expand Down Expand Up @@ -30,11 +30,7 @@ export class FieldExpressionExtension implements FormlyExtension {

if (field.expressionProperties) {
for (const key in field.expressionProperties) {
const expressionProperty = field.expressionProperties[key],
expressionValueSetter = evalExpressionValueSetter(
`field.${key}`,
['expressionValue', 'model', 'field'],
);
const expressionProperty = field.expressionProperties[key];

if (typeof expressionProperty === 'string' || isFunction(expressionProperty)) {
field._expressionProperties[key] = {
Expand All @@ -44,7 +40,6 @@ export class FieldExpressionExtension implements FormlyExtension {
? () => field.parent.templateOptions.disabled
: undefined,
),
expressionValueSetter,
};
if (key === 'templateOptions.disabled') {
Object.defineProperty(field._expressionProperties[key], 'expressionValue', {
Expand All @@ -57,7 +52,7 @@ export class FieldExpressionExtension implements FormlyExtension {
} else if (expressionProperty instanceof Observable) {
const subscription = (expressionProperty as Observable<any>)
.subscribe(v => {
this.setExprValue(field, key, expressionValueSetter, v);
this.setExprValue(field, key, v);
if (field.options && field.options._markForCheck) {
field.options._markForCheck(field);
}
Expand Down Expand Up @@ -157,8 +152,7 @@ export class FieldExpressionExtension implements FormlyExtension {
) {
markForCheck = true;
expressionProperties[key].expressionValue = expressionValue;
const setter = expressionProperties[key].expressionValueSetter;
this.setExprValue(field, key, setter, expressionValue);
this.setExprValue(field, key, expressionValue);
}
}

Expand Down Expand Up @@ -222,8 +216,20 @@ export class FieldExpressionExtension implements FormlyExtension {
}
}

private setExprValue(field: FormlyFieldConfigCache, prop: string, setter: Function, value: any) {
evalExpression(setter, { field }, [value, field.model, field]);
private setExprValue(field: FormlyFieldConfigCache, prop: string, value: any) {
try {
let target = field;
const paths = prop.split('.');
const lastIndex = paths.length - 1;
for (let i = 0; i < lastIndex; i++) {
target = target[paths[i]];
}

target[paths[lastIndex]] = value;
} catch (error) {
error.message = `[Formly Error] [Expression "${prop}"] ${error.message}`;
throw error;
}

if (prop === 'templateOptions.disabled' && field.key) {
this.setDisabledState(field, value);
Expand Down
2 changes: 0 additions & 2 deletions src/core/src/lib/services/formly.form.builder.spec.ts
Expand Up @@ -462,11 +462,9 @@ describe('FormlyFormBuilder service', () => {
builder.buildForm(form, [field], {}, {});
const disabledExpression = (field as FormlyFieldConfigCache)._expressionProperties['templateOptions.disabled'];
expect(typeof disabledExpression.expression).toBe('function');
expect(typeof disabledExpression.expressionValueSetter).toBe('function');

const labelExpression = (field as FormlyFieldConfigCache)._expressionProperties['templateOptions.label'];
expect(typeof labelExpression.expression).toBe('function');
expect(typeof labelExpression.expressionValueSetter).toBe('function');

expect(typeof field.hideExpression).toBe('function');
});
Expand Down

0 comments on commit 23edc3e

Please sign in to comment.