Angular app initializer chrome not redirecting to login page - google-chrome

I am using app_initializer in my angular to check for authorization details. If unauthenticated, redirecting to login page. It works perfectly fine locally and in test environment using Firefox. But in chrome it is not redirecting to the login page. Can anyone point me if there is any issue with my below code? Thanks
Injectable()
export class AppInitService {
private serviceUrl = '/v1/session';
private _http: HttpClient;
constructor(
#Inject(ENVIRONMENT) private _environment: Environment,
private sessionDetailsService: SessionDetailsService,
private httpBackend: HttpBackend
) {
this._http = new HttpClient(this.httpBackend);
}
init(): Promise<SessionDetailsResponse | unknown> {
return this._http
.get<SessionDetailsResponse>(
`${this._environment.apiBaseUrl}${this.serviceUrl}/details`
)
.pipe(
tap((sessionDetails) => {
this.sessionDetailsService.update(sessionDetails);
return sessionDetails;
}),
catchError((error) => {
handleUnauthorizedAccess(error, this._environment.baseUrl);
return of(null);
})
)
.toPromise();
}
}
export function handleUnauthorizedAccess(error: any, baseUrl: string) {
if (error.status === 401 && error.statusText === 'Unauthorized') {
const returnUrl = window.location.pathname;
const webUrl = `${baseUrl}/Account/Login?ReturnUrl=${encodeURIComponent(
returnUrl
)}`;
window.location.href = webUrl;
}
}
app.module
{
provide: APP_INITIALIZER,
useFactory: initialiseApp,
deps: [AppInitService],
multi: true
},
function initialiseApp(appInitService: AppInitService) {
return async () => {
const sessionDetailsResponse: SessionDetailsResponse | unknown =
await appInitService.init();
return sessionDetailsResponse;
};
}

Related

Angular11 using promise throwing A client-side or network error occurred: Uncaught (in promise): [object Undefined]

I have the following app initializer in my angular application. When deployed to test environment i am getting the following error
"A client-side or network error occurred: Uncaught (in promise): [object Undefined]"
app.module:
function initialiseApp(
appInitService: AppInitService
): () => Promise<SessionDetailsResponse> {
return async () => {
const sessionDetailsResponse: SessionDetailsResponse =
await appInitService.init();
return sessionDetailsResponse;
};
}
Here is my init service
#Injectable()
export class AppInitService {
private serviceUrl = '/v1/session';
private _http: HttpClient;
constructor(
#Inject(ENVIRONMENT) private _environment: Environment,
private sessionDetailsService: SessionDetailsService,
private httpBackend: HttpBackend
) {
this._http = new HttpClient(this.httpBackend);
}
init(): Promise<SessionDetailsResponse> {
return this._http
.get<SessionDetailsResponse>(
`${this._environment.apiBaseUrl}${this.serviceUrl}/details`
)
.toPromise()
.then((sessionDetails) => {
this.sessionDetailsService.update(sessionDetails);
return sessionDetails;
})
.catch((error) => {
handleUnauthorizedAccess(error, this._environment.baseUrl);
return Promise.reject();
});
}
}
export function handleUnauthorizedAccess(error: any, baseUrl: string) {
if (error.status === 401 && error.statusText === 'Unauthorized') {
const returnUrl = window.location.pathname;
const webUrl = `${baseUrl}/Account/Login?ReturnUrl=${encodeURIComponent(
returnUrl
)}`;
window.location.href = webUrl;
}
}

Using a service in angular 4 guards

Please assist with angular guards, I have the following angular Guard below :
export class RoleGuard implements CanActivate {
private role: any;
constructor(private router: Router, private accountService: AccountService)
{}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
this.accountService.getUserRole().subscribe(res => this.role = res);
if (this.role === 'admin') {
return true;
}
return false;
}
}
in the service:
getUserRole(): Observable<Response> {
const options = this.headers();
return this.http.get(`${environment.ApiUrl}/Roles/getRole`,options)
.map(res => res.json())
.catch(res => Observable.throw(res.json()));
}
I am trying to subscribe to the getUserRole() function, then assign the response to this.role but that is not happening, role is always undefined. when i do a ...subscribe(res => console.log(res)) i see the response data.
You have to wait the result of the async HTTP Request before check if can activate that route or not.
Try returning a new Observable instead:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return new Observable(observer => {
//
this.accountService.getUserRole().subscribe(role => {
//
if (role === 'admin') {
observer.next(true); // Allowing route activation
} else {
observer.next(false); // Denying route activation
}
}, err => observer.next(false));
});
}

Angular2 Authentication : there's something wrong with POST request?

Hi I am trying to authenticate users and once the server gives user's information, I want to use the information of the user.
But for some reasons, even though I did the log in process without any error and I can see from developer's tool that the POST request has been successful, I can't quite set currentUser in my localStorage (giving me null if I console.log it)
What am I doing wrong?
This is my authentication service.
export class AuthenticationService {
constructor(private http: Http, private router: Router) { }
login(email: string, password: string): Observable<User>{
const headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
headers.append('Access-Control-Allow-Headers', 'Content-Type');
headers.append('Access-Control-Allow-Methods', 'post');
headers.append('Access-Control-Allow-Origin', '*');
headers.append("X-Requested-With", "XMLHttpRequest");
let options = new RequestOptions({ headers: headers });
let body = new URLSearchParams();
body.set('email', email);
body.set('password', password);
return this.http.post(`${environment.baseurl}` + '/api/v2/member/login', body, options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let user = res.json();
if (user && user.token) {
localStorage.setItem('currentUser', JSON.stringify(user));
}
return user.data || {};
}
logout() {
// remove user from local storage to log user out
localStorage.removeItem('currentUser');
}
private handleError(error: any) {
if (error.status === 401) {
return Observable.throw(error.status);
} else {
return Observable.throw(error.status || 'Server error');
}
}
}
And this is my log-in component
export class LoginPageComponent implements OnInit {
constructor(private location: Location,
private route: ActivatedRoute,
private router: Router,
private authenticationService: AuthenticationService,
private alertService: AlertService) {
}
model: any = {};
loading = false;
returnUrl: string;
error = '';
ngOnInit() {
// get return url from route parameters or default to '/'
this.returnUrl = this.route.snapshot.queryParams['main'] || '/';
}
currentUser: User;
login() {
this.loading = true;
this.authenticationService.login(this.model.email, this.model.password)
.subscribe(
data => {
this.currentUser = data;
this.router.navigate([this.returnUrl]);
},
error => {
this.error = "Wrong ID or PW";
this.loading = false;
});
}
backClicked() {
this.location.back();
}
}
And this is my home component
export class MainComponent {
onClick() {
this.auth.logout() //if user clicks logout button
}
currentUser: User;
users: User[] = [];
items: Object[] = [];
constructor(private authguard: AuthGuard, private auth:AuthenticationService) {
this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
console.log(localStorage.getItem('currentUser')); //Printing null
}
}
And the model for user information is this.
export interface User {
birthday: number;
email:string;
genderType:string;
memberType: string;
name: string;
phone: string;
}
What im receiving
Why is it printing null?
Thank you!
Mistakes you made
passing email and password as URLSearchParams.
You are adding all the headers to your login method which is not necessary
The service should contain method as below
login(body: any, options?: RequestOptionsArgs): Observable<Response> {
return this.http.post('loginUrl', body);
}
Component should contain the below code
login() {
let user ={
email : this.model.email
password : this.model.password)
}
this.loading = true;
this.authenticationService.login(user)
.subscribe(data => {
this.authenticationService.extractData(data);///call to store token in the localstorage
this.router.navigate([this.returnUrl]);
},
error => {
this.error = "Wrong ID or PW";
this.loading = false;
});
}

Angular2 and Web API session control

i'm doing a login service. But i'm only capable of doing login, but i want to make a session to control the login's.
Where is my login.component.ts:
#Component({
selector: 'login',
templateUrl: './app/login/login.component.html'
})
export class LoginComponent implements OnInit {
model: any = {};
loading = false;
returnUrl: string;
constructor(
private route: ActivatedRoute,
private router: Router,
private utilizadorService: UtilizadoresService,
private alertService: AlertService) { }
ngOnInit() {
// reset login status
this.utilizadorService.logout();
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
login() {
console.log("Login! ");
this.loading = true;
this.utilizadorService.login(this.model.email, this.model.password).subscribe(
data => {
this.alertService.success('Login successful', true);
this.router.navigate(['/profile']);
},
error => {
this.alertService.error(error._body);
this.loading = false;
});
}
}
and there is my utilizadores.serice.ts, where is the login/register function:
#Injectable()
export class UtilizadoresService {
constructor(private _http: Http) {}
private RegenerateData = new Subject<number>();
// Observable string streams
RegenerateData$ = this.RegenerateData.asObservable();
AnnounceChange(mission: number) {
this.RegenerateData.next(mission);
}
LoadData(): Promise<IUtilizadores[]> {
return this._http.get('/api/utilizadores')
.toPromise()
.then(response => this.extractArray(response))
.catch(this.handleErrorPromise);
}
Add(model: IUtilizadores) {
let headers = new Headers({
'Content-Type':
'application/json; charset=utf-8'
});
let options = new RequestOptions({ headers: headers });
delete model["id"];
let body = JSON.stringify(model);
return this._http.post('/api/utilizadores/', body, options).toPromise().catch(this.handleErrorPromise);
}
Update(model: IUtilizadores) {
let headers = new Headers({
'Content-Type':
'application/json; charset=utf-8'
});
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify(model);
return this._http.put('/api/utilizadores/', body, options).toPromise().catch(this.handleErrorPromise);
}
Delete(id: number) {
return this._http.delete('/api/utilizadores/?id=' + id).toPromise().catch(this.handleErrorPromise);
}
login(email: string, password: string) {
return this._http.post('/api/utilizadores/login', { email: email, password: password })
.map((response: Response) => {
let utilizador = response.json();
if (utilizador) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(utilizador));
}
});
}
logout() {
// remove user from local storage to log user out
// localStorage.removeItem('id_token');
localStorage.removeItem('currentUser');
}
public authenticated() {
// Check if there's an unexpired JWT
// This searches for an item in localStorage with key == 'id_token'
return tokenNotExpired();
}
protected extractArray(res: Response, showprogress: boolean = true) {
let data = res.json();
return data || [];
}
protected handleErrorPromise(error: any): Promise<void> {
try {
error = JSON.parse(error._body);
} catch (e) {
}
let errMsg = error.errorMessage
? error.errorMessage
: error.message
? error.message
: error._body
? error._body
: error.status
? `${error.status} - ${error.statusText}`
: 'unknown server error';
console.error(errMsg);
return Promise.reject(errMsg);
}
}
export interface IUtilizadores {
id: number,
email: string,
nickname: string,
password: string
}
I'm doing this for a school project, so i dont want to work with Auth0, and i'm using VS 2015 and microsoft SQL server

Nativescript application-settings to persist a JSON value

I'm new to nativescript and angular 2 development. Currently, in the application that i'm building, HTTP post returns a JSON object like
[
{
"firstname": "test",
"isauth": true,
"lastname": "client",
"roleid": 10,
"rolename": "",
"userid": 3507,
"username": ""
}
]
I'm required to somehow save the userid (returned by Backendservice.apiUrl) value from the above response in login.component.ts and use that to pass to another API (Backendservice.requesturl ) that I'll be calling from another component(invoked clientmaster.component.ts). How do I do this on {N} + angular2.
Can I use applicationsettings setstring to persist the userid value and use it when I make the next call?If that's possible how do I parse the JSON response from the observable and save the userid value ?
I know that I can use flatmap to make chained http requests. But I'm not quite sure about how to do it and i'm very new to angular 2 development and RxJs observable concepts.
Here's my code:
login.service.ts
login(user: User) {
let headers = new Headers();
//In the headers object, the Content-Type specifies that the body represents JSON.
headers.append("Content-Type", "application/json");
let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', user.username);
urlSearchParams.append('pwd', user.password);
let body = urlSearchParams.toString();
console.log("body"+body);
return this.http.post(
BackendService.apiUrl,
body,
{headers: headers })
.map((response ) => {
response.json();
// login successful if there's a jwt token in the response
console.log("RESPONSE: "+response.url);
console.log("response json "+response.status);
var body = response.json();
console.log("JSON BODY: ",JSON.stringify(body));
}
)
.catch(this.handleErrors);
}
getAssociatedRequest(){
let headers = new Headers();
//call made to the next URL
return this.http.get(
BackendService.requestUrl
)
.map((response: Response) => {
// login successful if there's a jwt token in the response
console.log("RESPONSE: ",response);
var body = response.json();
console.log("JSON BODY: ",JSON.stringify(body));
alert(JSON.stringify(body));}
)
.catch(this.handleErrors);
}
logoff() {
BackendService.token = "";
}
handleErrors(error: Response) {
console.log(JSON.stringify(error.json()));
return Observable.throw(error);
}
}
login.component.ts
import { Component, ElementRef, OnInit, ViewChild } from "#angular/core";
.....
.....
#Component({
selector: "vp-login",
moduleId: module.id,
providers: [LoginService],
templateUrl: "./login.component.html",
styleUrls: ["./login.component.css", "./login.css"],
})
export class LoginComponent implements OnInit {
user: User;
isAuthenticating = false;
constructor(private router: Router,
private loginService : LoginService,
private page: Page) {
this.user = new User();
}
ngOnInit() {
this.page.actionBarHidden = true;
}
login() {
if (getConnectionType() === connectionType.none) {
alert("Vessel-Pro requires an internet connection to log in.");
return;
}
try {
this.loginService.login(this.user)
.subscribe(
() => {
this.isAuthenticating = false;
this.router.navigate(["/clientMaster"]);
},
(error) => {
alert("Unfortunately we could not find your account.");
this.isAuthenticating = false;
}
);
} catch (error) {
console.log(error.message);
}
}
}
clientmaster.component.ts
import { Component, ElementRef, OnInit, ViewChild } from "#angular/core";
import { alert, LoginService, User } from "../shared";
...
#Component({
selector: "clientMaster",
moduleId: module.id,
templateUrl: './clientmaster.component.html',
styleUrls: ["./clientmaster.component.css"],
providers: [LoginService]
})
export class ClientMasterComponent implements OnInit{
isLoading = false;
constructor(private router: Router,
private LoginService: LoginService,
private page: Page) {}
ngOnInit(){
this.page.actionBarHidden = true;
}
/**
* gotoSRTPage
*/
public gotoSRTPage() {
this.router.navigate(["srtDetails"])
}
loadsrt(){
// alert("OK");
if (getConnectionType() === connectionType.none) {
alert("Oops!! looks like your device is not connected to the internet ");
return;
}
this.LoginService.getAssociatedRequest()
.subscribe(
(response) => {
console.log("Success Response" + response)
},
(error) => { console.log("Error happened", error.message)},
() => { console.log("srt is completed")
}
);