Angular 2 - bypasscecurity - security

I habe problem with the "security" of angular 2. I try to calculate a span-witdh within a ngfor-loop:
<span style="width:updateStyle({{ ((date | amDifference : item.startdate : 'minutes' :true)/item.duration*100) | round }})% .....more span>
And import/changed a bypass-security.component from internet:
import { Component } from '#angular/core';
import { DomSanitizer, SafeStyle, SafeResourceUrl, SafeUrl } from '#angular/platform-browser';
#Component({
selector: 'bypass-security',
templateUrl: 'app/bypass-security.component.html',
})
export class BypassSecurityComponent {
dangerousUrl: string;
trustedUrl: SafeUrl;
dangerrousStyle: string;
trustedStyle: SafeStyle;
// #docregion trust-url
constructor(private sanitizer: DomSanitizer) {
// javascript: URLs are dangerous if attacker controlled.
// Angular sanitizes them in data binding, but you can
// explicitly tell Angular to trust this value:
this.dangerousUrl = 'javascript:alert("Hi there")';
this.trustedUrl = sanitizer.bypassSecurityTrustUrl(this.dangerousUrl);
this.trustedStyle = sanitizer.bypassSecurityTrustStyle(this.dangerrousStyle);
}
updateStyle(id: string)
{
this.trustedStyle = this.sanitizer.bypassSecurityTrustStyle(this.id);
}
}
But still get this error:
WARNING: sanitizing unsafe style value width:83%; height:3px; background-color:#d9d9d4; display:inline-block; (see http://g.co/ng/security#xss).
What can I do?
Thanks!

Calling methods from view bindings is usually bad practice because this method is called every time Angular2 checks for changes (runs change detection)
I don't really get what you try to accomplish, but if you want to set the width in % do something like
<span [style.width.%]="width">
and assign the value you want to be used for width to a property with that name
constructor() {
this.width = updateStyle(((date | amDifference : item.startdate : 'minutes' :true)/item.duration*100) | round }})
// I have a really hard time figuring out what this is supposed to do
I used the constructor only for an example. do the calculation whenever you think it should be updated (some event, some lifecycle callback, ...)

Related

Sometimes when I update the snapshots I got an Attribute __ngContext__

Sometimes when I update the snapshots I got an Attribute ngContext and for fix this problem I've to clean and install my node_modules to "fix" this issue.
I've to do this every time that I need to update a snapshot. I've already searched on multiple solutions and nothing worked.
snapshotSerializers: \[
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
\],
Can someone help me with this, please?
Here is an image
I've updated the jest versions and also the jest-present-angular too but didn't work.
I just want to have a solution that does not makes me clean install the node_modules every time
This is indeed annoying especially because it tends to change after upgrading angular version. My snapshots are now failing as well because of this difference :-/.
- __ngContext__={[Function LRootView]}
+ __ngContext__="0"
So, having look at the jest configuration, the snapshot serializers are being loaded from 'jest-preset-angular' module.
The relevant plugin here is 'jest-preset-angular/build/serializers/ng-snapshot'. Now, they are two ways what to do to get rid of __ngContext__.
replace the plugin entirely by a modified copy
Create a copy of that file in the same directory and adapt it accordingly (line https://github.com/thymikee/jest-preset-angular/blob/40b769b8eba0b82913827793b6d9fe06d41808d9/src/serializers/ng-snapshot.ts#L69):
const attributes = Object.keys(componentInstance).filter(key => key !== '__ngContext__');
Adapt the configuration:
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'./custom-snapshot-serializer.ts',
'jest-preset-angular/build/serializers/html-comment',
],
The disadvantage of this solution is that you have to maintain the plugin although only one line has been changed.
replace the plugin by a wrapper (preferred solution)
This creates just a wrapper for the original implementation. The idea is to remove __ngContext__ before it moves on down the plugin chain. However, the logic of the original plugin is used for the fixture serialization.
import type { ComponentRef, DebugNode, Type, ɵCssSelectorList } from '#angular/core';
import type { ComponentFixture } from '#angular/core/testing';
import type { Colors } from 'pretty-format';
import { test as origTest, print as origPrint } from 'jest-preset-angular/build/serializers/ng-snapshot';
/**
* The follow interfaces are customized heavily inspired by #angular/core/core.d.ts
*/
interface ComponentDef {
selectors: ɵCssSelectorList;
}
interface IvyComponentType extends Type<unknown> {
ɵcmp: ComponentDef;
}
interface NgComponentRef extends ComponentRef<unknown> {
componentType: IvyComponentType;
_elDef: any; // eslint-disable-line #typescript-eslint/no-explicit-any
_view: any; // eslint-disable-line #typescript-eslint/no-explicit-any
}
interface NgComponentFixture extends ComponentFixture<unknown> {
componentRef: NgComponentRef;
// eslint-disable-next-line #typescript-eslint/no-explicit-any
componentInstance: Record<string, any>;
}
/**
* The following types haven't been exported by jest so temporarily we copy typings from 'pretty-format'
*/
interface PluginOptions {
edgeSpacing: string;
min: boolean;
spacing: string;
}
type Indent = (indentSpaces: string) => string;
type Printer = (elementToSerialize: unknown) => string;
export const print = (fixture: any, print: Printer, indent: Indent, opts: PluginOptions, colors: Colors): any => {
const componentInstance = (fixture as NgComponentFixture).componentInstance;
const instance = { ...componentInstance };
delete instance.__ngContext__;
const modifiedFixture = { ...fixture, componentInstance: { ...instance } };
return origPrint(modifiedFixture, print, indent, opts, colors);
};
// eslint-disable-next-line #typescript-eslint/no-explicit-any, #typescript-eslint/explicit-module-boundary-types
export const test = (val: any): boolean => {
return origTest(val);
};
The configuration is adapted the same way as before.

NestJS/Express: Case-Insensitive Body Fields

I'm struggling to make the fields of my request DTOs case insensitive.
export class ExampleDto {
dateOfBirth?: string
}
Now I want to accept
{ "dateofbirth": "19880101" }
{ "dateOfBirth": "19880101" }
{ "DATEOFBIRTH": "19880101" }
My first thought was to implement a middleware which just looks at the incoming body and "extends it" with lower & upper case mappings for all incoming fields.
But that doesn't meet my requirements due to camel case, which I definitely want to keep as the default.
Any ideas on how to do this?
You could create a custom Pipe where you try the different options and finally return the Dto instance:
export class CaseInsensitiveExampleDtoPipe implements PipeTransform{
transform(body: any, metadata: ArgumentMetadata): ExampleDto {
const dto = new ExampleDto();
dto.dateOfBirth = body.dateOfBirth || body.dateofbirth || body.DATEOFBIRTH;
return dto;
}
In your controller you can then use it as follows:
#UsePipes(new CaseInsensitiveExampleDtoPipe())
async postNewExample(#Body() exampleDto: ExampleDto) {
// ...
}
Since JavaScript properties start existing after their initialization, you cannot "see" the definition of dateOfBirth?: string and therefor you won't be able to match it against the received JSON.
A possible solution for that is to enforce the creation of the properties of all of your DTO's with a constructor:
export class ExampleDto {
dateOfBirth: string
constructor(dateOfBirth: string){
this.dateOfBirth = dateOfBirth;
}
}
Then, you'll be able to iterate over the ExampleDto's properties and match them with a pipe (the received type can be derived from metadata):
#Injectable()
export class IgnoreCasePipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
const dto = new metadata.metatype;
const dtoKeys = Object.getOwnPropertyNames(dto);
Object.keys(value).forEach(key => {
const realKey = dtoKeys.find(dtoKey => dtoKey.toLocaleLowerCase() === key.toLocaleLowerCase());
if (realKey) {
dto[realKey] = value[key];
}
});
return dto;
}
}
Either inject it globally in main.ts or wherever it's needed - just bear in mind that you'll need to create a constructor for each DTO.
Note: this would work for a single-level class. If you want to support something like people: PersonDto[] in your classes then you'll need to recursively find all of the nested keys and match them - something like this.

How to share UI state in single-spa using RxJs?

As per the single-spa official doc, we can share the application's UI state by using RxJs.
Observables / Subjects (RxJs) - one microfrontend emits new values to
a stream that can be consumed by any other microfrontend. It exports
the observable to all microfrontends from its in-browser module, so
that others may import it.
Link: https://single-spa.js.org/docs/recommended-setup/#ui-state
Link: https://single-spa.js.org/docs/faq/#how-can-i-share-application-state-between-applications
I was trying to create an example in React, where I am using single-spa parcel to include my micro-apps in root application. I was trying to share the UI state using RxJs.
When I googled it for single-spa RxJs, I didn't find anything. Can anyone provide me a basic example where I will be able to share UI state for below use cases:
Sharing the UI state from root app to my micro-apps.
Sharing the UI state from micro-apps to root apps.
Sharing the UI state between micro-apps.
Here is a high level overview on how to approach this:
add rxjs as a shared dependency in your import map
"rxjs": 'https://unpkg.com/#esm-bundle/rxjs/system/rxjs.min.js,
"rxjs/operators": 'https://unpkg.com/#esm-bundle/rxjs/system/rxjs-operators.min.js,
consider pinning these to a specific version!
create a utility module (create-single-spa makes this easy!) that sets up and exports the observable with data that you need
include this utility module in importmap too
import and subscribe to observable from the utility module in the apps that need it
don't forget to unsubscribe when your apps unmount.
celebrate 🎉
I have created single-spa-example-rxjs-shared-state as an example repo that shows how to use an Rxjs utility module with cross-frontend imports.
This does the trick
In root html js file add the following
Import { Subject, Subscription } from 'https://dev.jspm.io/rxjs#6/_esm2015';
import { filter, map } from 'https://dev.jspm.io/rxjs#6/_esm2015/operators';
export class EventBusService {
constructor() {this.subject$ = new Subject(); }
emit(event) {
this.subject$.next(event);
}
on(eventName, action) {
return this.subject$.pipe(
filter( (e) => e.name === eventName),
map( (e) => e["data"])).subscribe(action);
}
}
var EventBus= new EventBusService()`enter code here`;
System.import('single-spa').then(function (singleSpa) {
singleSpa.registerApplication(
'app1',
function () {
return System.import('app1');
},
function (location) {
return true;
// return location.pathname.startsWith('/app1');
},
{ EventBus: EventBus }
);
singleSpa.registerApplication(
'app2',
function () {
return System.import('app2');
},
function (location) {
return true
// return location.pathname.startsWith('/app2');
},
{ EventBus: EventBus }
)
singleSpa.start();
})
In component
import { Component,OnInit ,ChangeDetectorRef} from '#angular/core';
import { assetUrl } from 'src/single-spa/asset-url';
import { singleSpaPropsSubject, SingleSpaProps } from 'src/single-spa/single-spa-props';
import { Subscription } from 'rxjs';
#Component({
selector: 'app1-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
singleSpaProps: SingleSpaProps;
subscription: Subscription;
title = 'app1';
yoshiUrl = assetUrl("yoshi.png");
msgFromMicro="";
titleToPass="";
constructor(private ChangeDetectorRef:ChangeDetectorRef){
}
ngOnInit(): void {
this.subscription = singleSpaPropsSubject.subscribe(
props => {
this.singleSpaProps = props;
console.log(props);
this.lookForEvents();
}
);
}
lookForEvents(){
this.singleSpaProps['EventBus'].on('msgFrmMicro2',(data)=>{
this.msgFromMicro=data;
this.ChangeDetectorRef.detectChanges();
});
}
sendMsg(){
// alert(this.titleToPass);
debugger;
this.singleSpaProps['EventBus'].emit({name:'msgFrmMicro1',data:this.titleToPass});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
Take look at the following repo, handled the same scenario by passing observable ref to micro apps through customprops of single spa
https://github.com/SENTHILnew/micro_spa_intercom

Getting an error that a property doesn't exist when it is showing up on the page accurately

I'm calling a twitter API from angular and then node, but I'm getting an error that a property doesn't exist on type 'Object'. But it is showing up on the page properly.
I've tried renaming the property and looked through the tweet service that I have set up, but I can't seem to figure out what's going wrong.
import { Component, OnInit } from '#angular/core';
import { TweetService } from '../../services/tweet.service';
#Component({
selector: 'app-twitter-page',
templateUrl: './twitter-page.component.html',
styleUrls: ['./twitter-page.component.scss']
})
export class TwitterPageComponent implements OnInit {
tweetsArray;
constructor(
private twitter: TweetService
) { }
ngOnInit() {
this.twitter.getTweets().subscribe(tweet => {
this.tweetsArray = tweet.tweets[0];
console.log(this.tweetsArray);
});
}
}
Error:
ERROR in src/app/main-body/twitter-page/twitter-page.component.ts(20,32): error TS2339: Property 'tweets' does not exist on type 'Object'.
Here tweet is of the type Object which do not have attributes on it.
You should define an interface ITweet and cast tweet to this interface. This gives a shape to the tweet object and defines the set of attributes available on it.
tweet.ts -
export interface ITweet {
...
};
twitter-page.component.ts - (note - .subscribe((tweet:ITweet) => {}))
import { ITweet } from './tweet.ts';
.
.
.
export class TwitterPageComponent implements OnInit {
.
.
.
ngOnInit() {
this.twitter.getTweets().subscribe((tweet:ITweet) => {
this.tweetsArray = tweet.tweets[0];
console.log(this.tweetsArray);
});
}
}
Or alternatively you can just cast tweet to any (.subscribe((tweet:any) => {})). But this is not recommended since you will lose the benefit of type checking.

React-native and Redux healthy way to call actions on props change

I've been using react-native with redux for a while, and the way i learn to call actions when something change on prop is using the componentWillReceiveProps, but when I use it I need to pass between if's and some times it goes to the wrong if, then I need to add more stuff to prevent it.
Here's an example I have done. I know this is not the best way to do it, but it is what I could think of.
componentWillReceiveProps(newProps) {
if(Object.keys(newProps.selected_product).length > 0) {
if(Object.keys(this.props.current_location).length > 0 || Object.keys(newProps.current_location).length > 0) {
this._handleNextPage(2);
this.props.verifyProductById(newProps.selected_product, newProps.current_location, this.props.token);
} else {
this.props.statusScanner(false);
this._handleNextPage(1);
}
} else if(Object.keys(newProps.historic_product_confirm).length > 0) {
if(newProps.historic_product_confirm.location._id == newProps.current_location._id)
this.props.handleModalConfirmPrice(!this.props.modal_confirmPrice_status)
} else if(newProps.scanResult != "") {
this.props.statusScanner(false);
if(Object.keys(newProps.current_location).length > 0) {
this._handleNextPage(2);
} else {
this._handleNextPage(1);
}
} else {
this._handleNextPage(0);
}
}
What I need is a healthy way to call my actions when the props change.
Edit:
Here i have the full OfferScene and an action file example:
OfferScene:
https://gist.github.com/macanhajc/0ac98bbd2974d2f6fac96d9e30fd0642
UtilityActions:
https://gist.github.com/macanhajc/f10960a8254b7659457f8a09c848c8cf
As mentioned in another answer, componentWillReceiveProps is being phased out, so I would aim for trying to eliminate it where possible. You'll be future-proofing your code and keeping your component logic more declarative and easy to reason about. As someone who has been responsible for (and been frustrated by) lifecycle method abuse like this, here are some things that have helped me.
Remember that when using redux-thunk, along with passing dispatch as the first argument, you can also pass getState as the second. This allows you to access state values in your action logic instead of bringing them into your component's props and adding clutter. Something like:
export const ExampleAction = update =>
(dispatch, getState) => {
const { exampleBool } = getState().ExampleReducer
if (exampleBool) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update
})
}
}
Using async/await in action logic can be a lifesaver when your action depends upon fetched results from an API call:
export const ExampleAction = () =>
async (dispatch, getState) => {
const { valueToCheck } = getState().ExampleReducer
, result = await someAPICall(valueToCheck)
.catch(e => console.log(e))
if (result.length > 0) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update: result
})
}
}
For cases where your component's rendering behavior depends upon certain state values after your state has been updated, I highly recommend reselect. A very basic example would be something like:
component.js
import React, { Component, Fragment } from 'react'
import { connect } from 'react-redux'
import { shouldDisplayItems } from '../selectors'
import MyListviewComponent from './myListview'
class ItemList extends Component {
render() {
const { shouldDisplayItems, items } = this.props
return (
<>
{shouldDisplayItems && <MyListviewComponent items={items} />}
</>
)
}
}
const mapStateToProps = ({ ListItems }) => shouldDisplayItems(ListItems)
export default connect(mapStateToProps)(ItemList)
selectors.js:
(Assuming your ListItems reducer has the params items and visibilityFilter)
import { createSelector } from 'reselect'
export const shouldDisplayItems = createSelector(
[state => state],
({ items, visibilityFilter }) => {
return {
shouldDisplayItems: visibilityFilter && items.length > 0,
items
}
}
)
I should mention that another option would be using higher-order components, but it can be tricky to use this approach before having a good grasp on how to keep too much imperative logic out of your components (I learned this the hard way).
I agree with #AnuragChutani and #Goldy in terms of clarity of the code; break it down some more into more components or functions.
Now after some review of your componentWillReceiveProps function, it is definitely not specific enough to narrow down exactly which prop changes. If any connected redux variable changes, the componentWillReceiveProps function will be invoked each time.
So e.g. if 'token' or 'selected_product' updates, componentWillReceiveProps will be triggered, even though you did not want it to trigger for token updates.
You can use a comparison for a specific variable update in the props.
E.g Using lodash
if(!_.isEqual( nextProps.selected_product, this.props.selected_product ))
// if props are different/updated, do something
Secondly, you can call actions/callbacks in your actions to narrow down navigation.
E.g.
takePicture = (camera, options){
...
//on success
dispatch(handleModalConfirmPrice())
...
}}

Resources