how to provide safety to ionic source code - javascript

hi it is always my question and worries about
is ionic application secured? is that possible to crack the ionic app and get the inside code or sth like this for example if my code is like this(add a service to my app)
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class EncryptionService {
url = 'https://api.amnas....com';
api-key='......'
constructor(private http: HttpClient) { }
newcheck(checkid: string ,cost: string,toname: string,tocode: string,passcode: string,date: string,checkfor: string,back: string): {
return this.http.get(`${this.url}?key=${this.api-key}&checkid=${encodeURI(checkid)}&cost=${encodeURI(cost)}&toname=${encodeURI(toname)}&tocode=${encodeURI(tocode)}&passcode=${encodeURI(passcode)}&date=${encodeURI(date)}&checkfor=${encodeURI(checkfor)}&back=${encodeURI(back)}`);
}
}
is that possible for anyone to crack my export app(apk) and extract api-key?

No matter how you build your application, any security keys, tokens, etc., are accessible to the client. You cannot rely on anything in your build remaining secret.

Related

Undefined config when injecting a config service

This is a follow-up of my previous post. I've been debugging this issue for quite a while now and even though I haven't fixed it, I made some discoveries so maybe someone will be able to help.
Here's the whole setup:
app-config.json (/src/assets/):
{
"apiUrl": "localhost:8080"
}
app-config.service.ts (/src/app/):
import {Injectable, Injector} from '#angular/core';
import {HttpClient} from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class AppConfigService {
private appConfig: any;
constructor (private injector: Injector) { }
loadAppConfig() {
let http = this.injector.get(HttpClient);
return http.get('/assets/app-config.json')
.toPromise()
.then(data => {
this.appConfig = data;
})
}
get config() {
return this.appConfig;
}
}
app.module.ts (/src/app/):
import {APP_INITIALIZER, NgModule} from '#angular/core';
import {HttpClientModule} from '#angular/common/http';
import {AppConfigService} from './app-config.service';
import {CometdService} from './cometd/cometd.service';
const appInitializerFn = (appConfig: AppConfigService) => {
return () => {
return appConfig.loadAppConfig();
}
};
#NgModule({
...
providers: [HttpClientModule,
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: appInitializerFn,
multi: true,
deps: [AppConfigService]
}]
})
export class AppModule {
constructor(cometdService: CometdService) {}
}
cometd.service.ts (/src/app/cometd/):
import {Injectable, OnDestroy} from '#angular/core';
import {Store} from '#ngrx/store';
import * as fromRoot from '../reducers';
import {AppConfigService} from '../app-config.service';
export interface CometDExtended extends cometlib.CometD {
websocketEnabled: boolean;
}
#Injectable({
providedIn: 'root'
})
export class CometdService implements OnDestroy {
protected cometd: CometDExtended = new cometlib.CometD() as CometDExtended;
private subscriptions: cometlib.SubscriptionHandle[] = [];
constructor(private environment: AppConfigService, private store: Store<fromRoot.State>) {
let config = environment.config;
let apiUrl = environment.config.apiUrl;
this.cometd.configure('http://localhost:8080/cometd');
this.startConnection();
}
...
}
The issue happens for various services. CometD is only an example.
The data in app-config.service.ts itself is fetched properly, i.e. loadAppConfig() returns { "apiUrl": "localhost:8080" }.
Injected environment (AppConfigService) is defined, i.e. it's of type Object.
environment.config is undefined, so environment.config.apiUrl returns an error: "TypeError: Cannot read properties of undefined (reading 'apiUrl')".
AppConfigService is not needed in providers array because providedIn: 'root' already make it available.
If you provide the service in different ways you may have multiple instances : one will be loaded, others would not.
If it still does not work, put a breakpoint to check if other services are created before the init completion. I recommand to move the calls out of the CometdService constructor, so you can perform the async call in a clean way
Welp, just minutes after posting the question I happened to find a solution. It seems like since loadAppConfig() is asynchronous, the environment.config might've been accessed before the promise was resolved. Changing the constructor to:
this.environment.loadAppConfig().then(() => {
let config = environment.config
...
});
fixed the issue.

BehaviourSubject.getValue() returning default values

I am fairly new to angular. I have two components namely header and profile component. The header component handles the login functionality and maintains two information- the user details which is json object and a isLoggedIn which is a boolean that saves current state of login. The general layout of the profile page is-
<header-component>
<profile-component>
Now since the header component handles the login. I want to avoid writing the logic for getting userDetails and the isLoggedIn status again for profile component. So i decided writing a shared service called profile service so that i can upload userDetails and isLogged from header and access that info in the profile component. The input in the loginlogout method comes from the header component.
SharedService code -
import { Injectable } from '#angular/core';
import { HttpService } from './https.service';
import { Observable, BehaviorSubject, of as observableOf } from 'rxjs';
import * as _ from 'lodash';
import { HttpHeaders, HttpParams } from '#angular/common/http';
import { BaseService } from './base.service';
#Injectable()
export class ProfileServices{
constructor(){};
userDetailsBS = new BehaviorSubject<any>('original value');
userDetails= this.userDetailsBS.asObservable();
isLoggedIn:boolean;
loginlogout(userDetails:any , isLoggedIn:boolean){
this.userDetails=userDetails;
this.userDetailsBS.next(this.userDetails);
console.log("Value of user details set in profile service",this.userDetails); //debug
console.log(".getValue() method:",this.userDetailsBS.getValue()); //debug
this.isLoggedIn=isLoggedIn;
}
getUserDetails(){
return this.userDetailsBS.getValue();
}
}
Post login from the header-component.ts i call the loginlogout method in the profile service to set the values. I also tried to access the value passed to the shared Service using the getUserDetails which shows that the userDetails object is passed correctly to the shared service.
The issue arises when i try to access the data from the profile component-
export class ProfileT1Component implements OnInit {
userDetails:any;
constructor(
public profileService: ProfileServices){
this.profileService.userDetails.subscribe((result)=>{
console.log(result);
this.userDetails=result;
console.log("received user details in profile component constructor: ", this.userDetails);
})
}
}
the result still shows "original value" and not the updated value. Is this wrong approach altogether or am i handling the observables incorrectly. Help would be much appreciated.
You need to make a couple of changes in your service to make it work. Add providedIn: root and remove all declarations from other modules. Secondly, you do not need this.userDetailsBS.asObservable() and you can use the subscribe directly on userDetailsBS. Your code will look something like the following.
Service:
#Injectable({
providedIn: 'root'
})
export class ProfileServices {
constructor() {}
userDetailsBS = new BehaviorSubject<any>('original value');
isLoggedIn: boolean;
loginlogout(userDetails: any, isLoggedIn: boolean) {
this.userDetailsBS.next(userDetails);
this.isLoggedIn = isLoggedIn;
}
getUserDetails() {
return this.userDetailsBS.getValue();
}
}
Component:
export class ProfileT1Component implements OnInit {
userDetails: any;
constructor(public profileService: ProfileServices) {
this.profileService.userDetailsBS.subscribe((result) => {
console.log(result);
this.userDetails = result;
console.log('received user details in profile component constructor: ', this.userDetails);
});
}
}
the implementation seems to be OK
(except you should make the BehaviorSubject private and expose only the observable)
probably you have multiple instance of the service.
try to add :
#Injectable({
providedIn: 'root',
})
and remove the service declaration from all the modules provider array
https://angular.io/guide/singleton-services

Angular 7 Service providedIn: 'root'

I'm very new to angular development so please forgive me if this is a very basic question
But I have a cart service which I have at the moment simply has a simple console log function
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class CartService {
constructor( ) {}
public addItem() {
console.log('Hello');
}
}
and basically I cannot figure out how to use this service within a NG Module that I have installed, I have successfully used it in other components via the constructor but the ngmodule doesn't have this?
I get the fact that it's a singleton at the app-module level by using the providedIn: 'root' tag added in angular 6
but just can't figure out how to call cartService.addItem()?
Thanks if anyone can help!
You can use Dependency Injection like this to call the service
export class AppComponent {
constructor(private cartService: CartService) {
}
doSomething() {
this.cartService.addItem();
}
}
Below is the sample code of how to use service in component:
Component.ts
import { Component, OnInit} from '#angular/core';
import { yourSeerviceName } from "PATH_TO_SERVICE";
#Component({
selector: 'app-dummy',
styleUrls: ['dummy.component.sass'],
templateUrl: 'dummy.component.html'
})
export class yourComponent implements OnInit {
// you can provide any name for variable it's upto you
constructor(private dummyService:yourSeerviceName) {
}
//access the method in you'r service by performing below action.
this.dummyService.yourMethod();
}
If you created a new module, you need to introduce the service to your module, by going to the .module.ts file and adding your service to the providers array. It will be something like:
providers: [
CartService
],

Cannot use simple map?

I'm following this tutorial: https://www.youtube.com/watch?v=KhzGSHNhnbI&t=527s
And at 51:41 he uses map. But my code doesn't work. Why I can't use it? I get
Property map does not exists on Observable <Response>
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(public http:Http) {
console.log("Data service connected...");
}
getPosts() {
this.http.get('https://jsonplaceholder.typicode.com/posts').map(res => res.json());
}
}
Service code you provide is using angular 6 which has dependency of rxjs 6.
So from rxjs 6 onwards you have to use pipeable operators and import paths are modified. so please change the code as follows
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(public http:HttpClient) {
console.log("Data service connected...");
}
getPosts() {
this.http
.get('https://jsonplaceholder.typicode.com/posts')
.pipe(
map(res => res.json())
);
}
}
And one more recommendation please start using HttpClient Module instead of Http Module. So even you dont need to use map to get json response
Please check this link for httpClient Module

Communicate with backend through Angular

I have a developed a small library (js code) that I want to integrate with angular. the problem is that this library at a certain moment should make request ( ajax ) to push some results to the back-end. How can I make that in angular ? should I develop directives to support binding ?
Sorry I have small knowlege in angular but whats the best way to send data collected by the front end to backend.
thanks
The best way to interact with backend is to use services. For example (the example is for the latest Angular version, previous versions doesn't support HttpClient, it's just Http. I also use toPromise, it's optional, you can deal with observable if you want):
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class YourService {
constructor(
private _http: HttpClient
) { }
public sendDataToServer(data: any): Promise<any> {
return this._http.post(http://fakehost/fakeurl, data)
.toPromise()
.catch(err => console.error(err));
}
And inside your component:
import { Component } from '#angular/core';
import { YourService } from '../../core/your-service.service';
#Component({
selector: 'your-component',
templateUrl: './your-component.component.html',
styles: [``]
})
export class SignUpComponent {
constructor(private _yourService: YourService) {
this.ApiCall();
}
public ApiCall(): void {
this._yourService.sendDataToServer("any data here")
.then(response => {
console.log("Response:", response);
})
.catch(err => console.error(err));
}
}

Categories

Resources