I have trying to implement auth provider for Node application which uses JWT
I'm getting error
TypeError: Cannot read property 'set' of undefined
My app.module.ts look like below.
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { LoginPage } from '../pages/login/login';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HttpModule } from '#angular/http';
import { Auth } from '../providers/auth/auth';
import { Storage } from '#ionic/storage';
export function provideStorage() {
return new Storage( { name: '__mydb' } /* optional config */);
}
#NgModule({
declarations: [
MyApp,
HomePage,
LoginPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
HttpModule,
// IonicStorageModule.forRoot({
// name: '__mercury',
// driverOrder: ['indexeddb', 'websql']
// })
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
LoginPage
],
providers: [
StatusBar,
SplashScreen,
LoginPage,
{ provide: Storage, useFactory: provideStorage },
{ provide: ErrorHandler, useClass: IonicErrorHandler },
Auth
]
})
export class AppModule { }
I used documentation in https://github.com/driftyco/ionic-storage/tree/v2.0.1#configuring-storage-new-in-117
My auth.provider.ts
import { Injectable } from '#angular/core';
import { Http, Response, Headers } from '#angular/http';
import 'rxjs';
import { Storage } from '#ionic/storage';
/*
Generated class for the AuthProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class Auth {
baseUrl: string = "http//localhost:9080/"
constructor(public http: Http, public storage: Storage) {
console.log('Hello AuthProvider Provider');
}
createAuthorizationHeader(headers: Headers) {
let token;
this.storage.get('token').then(data => token = data);
headers.append('Athorization', token);
}
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map(this.extractData);
}
isLogged() {
this.storage.get('token').then(data => {
if (data)
return true;
else
return false;
}).catch(err => {
return false;
});
return false;
}
logout() {
this.storage.remove('token');
return true;
}
private extractData(res: Response) {
console.log(res);
let body = res.json();
if (body.success === true) {
this.storage.set("token", body.token);
};
return body || {};
}
}
My platform details are
Ionic Framework: 3.2.1
Ionic Native: ^3.5.0
Ionic App Scripts: 1.3.7
Angular Core: 4.1.0
Angular Compiler CLI: 4.1.0
Node: 6.10.3
OS Platform: macOS Sierra
Navigator Platform: MacIntel
Ionic Storage : ^2.0.1
Change
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map(this.extractData);
}
to
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map(this.extractData.bind(this));
}
or
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map((data)=>this.extractData(data));
}
Your this is not refering to your component
Related
I want to add authentication to my graphql app in nestjs. the token I receive is from auth0.
Im fairly new to nestjs I have looked at its documentation. this is the best I could comeup with and it still isnt working
this is my code where Im trying to add auth
app.module
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { MongooseModule } from '#nestjs/mongoose';
import { databaseConfig, applicationConfig } from '../../config/';
import MongoServiceClass from '../../services/Mongo';
import { ConfigModule as AppConfigModule } from '../config/config.module';
import { GraphQLModule } from '#nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '#nestjs/apollo';
import { LoggingPlugin } from 'src/plugins/LoggerCustom';
import { UserModule } from './user/user.module';
import { QuotaModule } from './quota/quota.module';
import { QuotaManagementModule } from './quota-management/quota-management.module';
import { BobModule } from './bob/bob.module';
import { SlModule } from './sl/sl.module';
import { SlQModule } from './sl-q/sl-q.module';
import { AuthModule } from '../auth/auth.module';
const NODE_ENV = process.env.NODE_ENV;
#Module({
imports: [
LoggingPlugin,
ConfigModule.forRoot({
load: [applicationConfig, databaseConfig],
envFilePath: `.env.${NODE_ENV}`,
isGlobal: true,
}),
MongooseModule.forRootAsync({
useClass: MongoServiceClass,
}),
AuthModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
autoSchemaFile: 'schema.gql',
driver: ApolloDriver,
path: '/graphql',
playground: true,
debug: true,
}),
BobModule,
QuotaModule,
QuotaManagementModule,
AppConfigModule,
SlQModule,
SlModule,
UserModule,
],
})
export class AppModule {}
auth.module
import { Global, Module } from '#nestjs/common';
import { UserModule } from '../app/user/user.module';
import { AuthService } from './auth.service';
import { AuthResolver } from './auth.resolver';
import { GqlAuth0Guard } from './gql.guard';
import { GqlAuth0JwtStrategy } from './gql-auth0-jwt.strategy';
import { PassportModule } from '#nestjs/passport';
#Global()
#Module({
imports: [UserModule, PassportModule.register({ defaultStrategy: 'jwt' })],
providers: [AuthService, AuthResolver, GqlAuth0JwtStrategy, GqlAuth0Guard],
})
export class AuthModule {}
gql-auth0-jwt.strategy
import { Injectable, UnauthorizedException } from '#nestjs/common';
import { PassportStrategy } from '#nestjs/passport';
import { Strategy as BaseStrategy, ExtractJwt, VerifiedCallback } from 'passport-jwt';
import { passportJwtSecret } from 'jwks-rsa';
#Injectable()
export class GqlAuth0JwtStrategy extends PassportStrategy(BaseStrategy) {
domain = 'https://dev-ab454a.us.auth0.com/';
constructor() {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://dev-ab454a.us.auth0.com/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: 'https://hyyype-app.herokuapp.com/',
issuer: 'https://dev-ab454a.us.auth0.com/',
});
}
validate(payload: any, done: VerifiedCallback) {
console.log('Validate JWT-STRATEGY');
if (!payload) {
done(new UnauthorizedException(), false);
}
return done(null, payload);
}
}
gql.guard
import { ExecutionContext, Injectable } from '#nestjs/common';
import { GqlExecutionContext } from '#nestjs/graphql';
import { AuthGuard } from '#nestjs/passport';
#Injectable()
export class GqlAuth0Guard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
console.log('GQL-AUTH0-GUARD');
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
auth.resolver
import { UnauthorizedException, UseGuards } from '#nestjs/common';
import { Query, Resolver } from '#nestjs/graphql';
import { CurrentUser } from './auth.decorator';
import { GqlAuth0Guard } from './gql.guard';
#Resolver()
export class AuthResolver {
#Query(() => String)
#UseGuards(GqlAuth0Guard)
getAuthenticatedUser(#CurrentUser() user: any) {
if (!user) {
throw new UnauthorizedException('Get Auth User');
}
return user;
}
}
this is my response after i send a request I have checked the token is valid
GQL-AUTH0-GUARD
error: 586ms - Unauthorized
I'm working on migrating my Angular 10 application to SSR using Angular universal and I'm facing issues with ngx-translate while translating parameterised values.
I have a translation
Bei Kauf von {quantity}
where this quantity is an attribute from our component and we normally translate it like
{{ 'LABEL' | translate: {quantity: 1} }} and we will see Bei Kauf von 1
But with SSR it's not at all translating. I see Bei Kauf von {quantity} on the page. I checked many forums and I don't see potential solutions. Any help would be much appreciated.
Here is my translate-server.loader.ts
import { join } from 'path';
import { Observable } from 'rxjs';
import { TranslateLoader } from '#ngx-translate/core';
import {
makeStateKey,
StateKey,
TransferState
} from '#angular/platform-browser';
import * as fs from 'fs';
export class TranslateServerLoader implements TranslateLoader {
constructor(
private transferState: TransferState,
private prefix: string = 'i18n',
private suffix: string = '.json'
) {}
public getTranslation(lang: string): Observable<any> {
return new Observable((observer) => {
const assets_folder = join(
process.cwd(),
'dist',
'my-app',
'browser',
'assets',
this.prefix
);
const jsonData = JSON.parse(
fs.readFileSync(`${assets_folder}/${lang}${this.suffix}`, 'utf8')
);
// Here we save the translations in the transfer-state
const key: StateKey<number> = makeStateKey<number>(
`transfer-translate-${lang}`
);
this.transferState.set(key, jsonData);
observer.next(jsonData);
observer.complete();
});
}
}
export function translateServerLoaderFactory(transferState: TransferState) {
return new TranslateServerLoader(transferState);
}
translate-browser.loader.ts
import { Observable } from 'rxjs';
import { TranslateLoader } from '#ngx-translate/core';
import {
makeStateKey,
StateKey,
TransferState
} from '#angular/platform-browser';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
import { HttpClient } from '#angular/common/http';
export class TranslateBrowserLoader implements TranslateLoader {
constructor(private http: HttpClient, private transferState: TransferState) {}
public getTranslation(lang: string): Observable<any> {
const key: StateKey<number> = makeStateKey<number>(
`transfer-translate-${lang}`
);
const data = this.transferState.get(key, null);
// First we are looking for the translations in transfer-state,
// if none found, http load as fallback
if (data) {
return new Observable((observer) => {
observer.next(data);
observer.complete();
});
} else {
return new TranslateHttpLoader(this.http).getTranslation(lang);
}
}
}
export function translateBrowserLoaderFactory(
httpClient: HttpClient,
transferState: TransferState
) {
return new TranslateBrowserLoader(httpClient, transferState);
}
app.server.module.ts
import { NgModule } from '#angular/core';
import { ServerModule, ServerTransferStateModule } from '#angular/platform-server';
import { FlexLayoutServerModule } from '#angular/flex-layout/server';
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { translateServerLoaderFactory } from './shared/loaders/translate-server.loader';
import { TransferState } from '#angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { EnvironmentService } from '~shared/services/environment.service';
#NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateServerLoaderFactory,
deps: [TransferState]
}
}),
FlexLayoutServerModule,
],
providers: [EnvironmentService],
bootstrap: [AppComponent],
})
export class AppServerModule {}
app.module.ts
imports: [
....,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateBrowserLoaderFactory,
deps: [HttpClient, TransferState]
}
}),
]
Note: It's working fine for all others which don't have any parameterised values in translations
It should be double curly brackets
Bei Kauf von {{quantity}}
wanna notice 2 more things, idk if it changed in last versions of Angular, but don't forget to register TransferState in app.module providers
providers: [
TransferState,
...
]
and for translate-server.loader.ts if you have some type errors for node.js use
/// <reference types="node" /> // add this line
import {join} from 'path';
at the top.
If it doesn't help, try to add
"types" : ["node", "express"],
to your tsconfig.json inside "compilerOptions"
It took me some time))
I faced with next error and cannot understand how to resolve it.
Error: Can't resolve all parameters for LoginPage: ([object Object], [object Object], [object Object], ?).
I've checked almost every topic here and have tried multiple ways to resolve it but still can't beat it already second day.
Login.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams,AlertController } from 'ionic-angular';
import { AuthProvider } from '../../providers/auth/auth';
import { TabsPage } from '../tabs/tabs';
/**
* Generated class for the LoginPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
email:string = '';
password:string = '';
errorMsg:string;
constructor(
public navParams: NavParams,
public navCtrl: NavController,
public alertCtrl: AlertController
public authService: AuthProvider,
) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad LoginPage');
}
errorFunc(message){
let alert = this.alertCtrl.create({
title: 'oops!',
subTitle: message,
buttons: ['OK']
});
alert.present();
}
myLogIn(){
if (this.email.trim() !=='' ) {
console.log(this.email.trim() + " " + this.password.trim() )
if (this.password.trim() === '') {
this.errorFunc('Please put your password')
}
else{
let credentials = {
email: this.email,
password: this.password
};
this.authService.login(credentials).then((result) => {
console.log(result);
this.navCtrl.setRoot(TabsPage);
}, (err) => {
console.log(err);
this. errorFunc('Wrong credentials ! try again')
console.log("credentials: "+JSON.stringify(credentials))
});
}
}
else{
this. errorFunc('Please put a vaild password ! for ex:(123456)')
}
}
myLogOut(){
this.authService.logout();
}
}
Auth.ts
import { Injectable } from '#angular/core';
import { Storage } from '#ionic/storage';
import { Http , Headers } from '#angular/http';
import { TabsPage } from '../../pages/tabs/tabs';
#Injectable()
export class AuthProvider {
rootPage:any = TabsPage;
public token:any;
constructor(public storage:Storage ,public http: Http) {
console.log('Hello AuthProvider Provider');
}
login(credentials){
return new Promise((resolve, reject) => {
let headers = new Headers();
headers.append('Access-Control-Allow-Origin' , '*');
headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
headers.append('Accept','application/json');
headers.append('Content-type','application/json');
headers.append('X-Requested-With','XMLHttpRequest');
this.http.post('http://127.0.0.1:8000/api/auth/login', JSON.stringify(credentials), {
headers: headers})
.subscribe(res => {
let data = res.json();
this.token = data.token;
localStorage.setItem('token',data.access_token);
resolve(data);
}, (err) => {
reject(err);
}); });
}
checkAuthentication(){
return new Promise((resolve, reject) => {
this.storage.get('token').then((value) => {
this.token = value;
resolve(this.token)
})
});
}
logout(){
localStorage.setItem('token','');
}
}
app.moodule.ts
import { NgModule, ErrorHandler } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { IonicStorageModule } from '#ionic/storage';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
import { LoginPage } from '../pages/login/login';
import { AddPage } from '../pages/add/add';
import { AuthProvider } from '../providers/auth/auth';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HttpModule } from '#angular/http';
import { ComplaintProvider } from '../providers/complaint/complaint';
#NgModule({
declarations: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage,
LoginPage,
AddPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
IonicStorageModule.forRoot(),
HttpModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage,
LoginPage,
AddPage
],
providers: [
StatusBar,
SplashScreen,
AuthProvider,
ComplaintProvider,
{provide: ErrorHandler, useClass: IonicErrorHandler},
]
})
export class AppModule {}
You seem to be having a classic circular reference going around. You have the "TabsPage" imported in both Auth.ts & in your "LoginPage.ts".
A Classic Circular Reference.
Try removing the TabsPage from Auth.ts. In general, it is best if you have your components do very specific things so that you have a granular code and avoid such circular reference issues.
I am testing an angular 7 component that uses angular js components inside.
I am using jasmine and karma for testing.
I am getting
Angular Hybrid - **Error: Trying to get the AngularJS injector before it being set.** when I am running the ng test my-app-name.
app-module-ts -
import { BrowserModule } from '#angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '#angular/core';
import { UpgradeModule, downgradeComponent } from '#angular/upgrade/static';
import { AppComponent } from './app.component';
import { BusyOverlayModule } from '../../../app-shared/src/lib/busy-overlay/busy-overlay.module';
import { L10nTranslationModule } from '../../../app-shared/src/lib/l10n-translation/l10n-translation.module';
import { LocalizationService } from '../../../app-shared/src/lib/l10n-translation/localization.service';
import { WatchlistModule } from './watchlist/watchlist.module';
import oprRtsmViewPickerModuleName
from '../../../../../../shared/shared-html/js/directives/oprRtsmViewPicker/oprRtsmViewPicker.module.js';
import oprTableFooterModuleName
from '../../../../../../shared/shared-html/js/directives/oprTableFooter/oprTableFooter.module.js';
import oprContextPanelModuleName
from '../../../../../../shared/shared-html/js/directives/oprContextPanel/oprContextPanel/oprContextPanel.module.js';
import { FilterFactory } from 'angular';
import oprPopupServiceModuleName from '../../../../../../shared/shared-html/js/services/oprPopup.service';
import ciContextDataServiceModuleName from '../../../../../../shared/shared-html/js/services/ciContextData.service';
import watchlistOptionsLauncherComponent from './watchlist/options-menu/watchlistOptionsLauncherNg1';
import oprLocalizationUtil from '../../../../../../shared/shared-html/js/utils/oprLocalizationUtil';
import appConstantsUtil from '../../../../../../shared/shared-html/js/utils/appConstantsUtil';
import { setAngularJSGlobal } from '#angular/upgrade/static';
import { oprContextPanelApiServiceProvider } from '../../../ng1-adapters/adapters/opr-conext-panel-api-provider';
import { ciContextDataServiceProvider } from '../../../ng1-adapters/adapters/opr-conext-data-api-provider';
import { Oprl10nPipe } from '../../../app-shared/src/lib/l10n-translation/oprl10n.pipe';
declare const angular: angular.IAngularStatic;
setAngularJSGlobal(angular);
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
UpgradeModule,
BusyOverlayModule,
L10nTranslationModule,
WatchlistModule
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: onAppInit,
multi: true
},
oprContextPanelApiServiceProvider,
ciContextDataServiceProvider,
Oprl10nPipe
],
entryComponents: [
AppComponent
]
})
export class AppModule {
constructor(private upgrade: UpgradeModule, private localizationService: LocalizationService) { }
/**
* bootstrap hybrid AngularJS/Angular application with downgraded root Angular component
*/
ngDoBootstrap() {
const ng1L10nfilterFactory: angular.Injectable<FilterFactory> = function () {
return (key) => {
return oprLocalizationUtil.getLocalizedString(key);
};
};
const ng1RootModule = angular.module('ng1-root', [
oprPopupServiceModuleName,
oprRtsmViewPickerModuleName,
oprTableFooterModuleName,
oprContextPanelModuleName,
ciContextDataServiceModuleName
]).directive('oprRoot', downgradeComponent({component: AppComponent})).filter('oprL10n', ng1L10nfilterFactory)
.component('oprOptionsMenuLauncher', watchlistOptionsLauncherComponent);
this.localizationService.setOprLocalizeUtilObj(oprLocalizationUtil);
this.upgrade.bootstrap(document.body, [ng1RootModule.name], {strictDi: false});
}
}
export function onAppInit(): () => Promise<any> {
return (): Promise<any> => {
return new Promise((resolve, reject) => {
const appConstants = appConstantsUtil.appConstants;
/**
* For Testing, Replace this appConstants.locale.toLowerCase() code with en
*/
oprLocalizationUtil.init(appConstants.locale.toLowerCase(), appConstants.staticContext, [
'opr-watchlist',
'opr-common'
], function () {
resolve(true);
});
});
};
}
app.component.ts -
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'opr-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
showBusyOverlay:boolean = true;
ngOnInit() {
this.showBusyOverlay = false;
}
}
app.component.spec.ts -
import { TestBed, ComponentFixture, async } from '#angular/core/testing';
import * as angular from '#angular/upgrade/src/common/angular1';
import { UpgradeModule, setAngularJSGlobal } from '#angular/upgrade/static';
import { AppComponent } from './app.component';
import { AppSharedModule } from "../../../app-shared/src/lib/app-shared.module";
import { WatchlistComponent } from './watchlist/watchlist.component';
import { WatchlistFooterComponent } from './watchlist/watchlist-footer/watchlist-footer.component';
import { WatchlistHeaderComponent } from './watchlist/watchlist-header/watchlist-header.component';
import { WatchlistCardsComponent } from './watchlist/watchlist-cards/watchlist-cards.component';
import { WatchlistCardComponent } from "./watchlist/watchlist-cards/watchlist-card/watchlist-card.component";
import { WatchlistCardsModule } from './watchlist/watchlist-cards/watchlist-cards.module';
import { WatchlistModule } from './watchlist/watchlist.module';
import { ContextPanelApi } from 'shared/directives/oprContextPanel/oprContextPanel/oprContextPanelApi.service';
import { CiContextDataService } from '../../../../../../shared/shared-html/js/services/ciContextData.service';
import { CiContextMenuService } from '../../../app-shared/src/lib/ci-context-menu.service';
import { HttpClientModule, HttpClientXsrfModule } from '#angular/common/http';
import { Ng1AdaptersModule } from '../../../ng1-adapters/ng1-adapters.module';
import { FormsModule } from '#angular/forms';
import { BusyOverlayModule } from '../../../app-shared/src/lib/busy-overlay/busy-overlay.module';
import { L10nTranslationModule } from '../../../app-shared/src/lib/l10n-translation/l10n-translation.module';
import '../../../../../../shared/shared-html/test/config/index-mock.js';
import { Oprl10nPipe } from "../../../app-shared/src/lib/l10n-translation/oprl10n.pipe";
import { of } from 'rxjs';
export class MockBusyOverlayModule {
}
export class MockContextPanelApi {
}
export class MockCiContextDataService {
}
export class MockCiContextMenuService {
}
export class Oprl10nPipeStub {
public get(key: any): any {
return of(key);
}
public transform(key: any): any {
return of(key);
}
}
setAngularJSGlobal(angular);
describe('AppComponent', () => {
window['getAppConstants'] = function () {
return JSON.stringify({
topazWebContext: "",
mashupParams: { uim_sourceId: "0" },
staticContext: "/base",
locale: "en-us",
oprWebContext: ""
});
};
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
UpgradeModule,
BusyOverlayModule,
HttpClientModule,
AppSharedModule,
// appConstantsUtil,
// WatchlistModule,
Ng1AdaptersModule,
L10nTranslationModule,
// WatchlistModule
// WatchlistCardsModule
],
providers: [
{ provide: Oprl10nPipe, useClass: Oprl10nPipeStub },
// { provide: BusyOverlayModule, useClass: MockBusyOverlayModule }
{ provide: ContextPanelApi, useClass: MockContextPanelApi },
{ provide: CiContextDataService, useClass: MockCiContextDataService },
{ provide: CiContextMenuService, useClass: MockCiContextMenuService },
// { provide: appConstantsUtil }
],
declarations: [
AppComponent,
WatchlistComponent,
WatchlistFooterComponent,
WatchlistHeaderComponent,
WatchlistCardComponent,
WatchlistCardsComponent
]
// imports: [
// WatchlistModule
// ]
}).compileComponents();
}));
beforeEach(() => {
window['getAppConstants'] = function () {
return JSON.stringify({
topazWebContext: "",
mashupParams: { uim_sourceId: "0" },
staticContext: "/base",
locale: "en-us",
oprWebContext: ""
});
};
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create the app', () => {
expect(component).toBeTruthy();
});
});
My angular js version is 1.6 and Angular 7, as I said I am testing angular 7 components that use angular js components.
I found some links on web -
Angular Hybrid Error: Trying to get the AngularJS injector before it being set
https://github.com/angular/angular/issues/23141
but no help. I am not able to find anything in the angular doc as well.
Please guide.
I solved this by adding
const upgrade = TestBed.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document);
const serviceWhichReliesonInjector =
to my beforeEach Method.
afterwards i could simply access the service by
TestBed.get(ServiceWhichReliesonInjector)
So I'm trying to set up a sso system with keycloak on my angular app.
I have downloaded the keycloak library keycloak-angular#4.0.2, setted up a keycloak server at localhost:8080/auth, added the keycloak.json on the root of the app, that keycloak made for me:
{
"realm": "my-app",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "my-app",
"public-client": true,
"confidential-port": 0
}
Also I added the keycloak initi function in the main.ts:
import { enableProdMode } from '#angular/core';
//....some other import....
import { KeycloakService } from 'keycloak-angular';
var injector = ReflectiveInjector.resolveAndCreate([KeycloakService]);
var keycloak = injector.get(KeycloakService)
if (environment.production) {
enableProdMode();
}
keycloak.init()
.then(() => platformBrowserDynamic().bootstrapModule(AppModule))
.catch(e => {
console.error(e);
});
Now, if I try to make a registration page, something like this:
export class registration implements OnInit {
constructor(keycloak:KeycloakService) {
keycloak.register();
}
ngOnInit() {
}
}
It works and sends me to a registration page and if I create an account it appears in the keycloak server.
BUT... even if I am not logged in with any account it lets me access any page, also, if I try:
keycloak.isLoggedIn().then(() => console.log("logged"), ()=>console.log("Not logged"));
The result is "logged", but if I try:
keycloak.loadUserProfile();
Then it says
The user profile was not loaded as the user is not logged in.
I can't understand how it works, am I missing something?
So my question is:
- How do I prevent pages to show if I am not logged in?
- How do I make a user log and stay logged and angular to recognize who is logged and who is not.
UPDATE: As asked I'm adding app.module.ts
import { BrowserModule, HAMMER_GESTURE_CONFIG } from '#angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '#angular/core';
import { TranslateModule } from '#ngx-translate/core';
import { HttpClientModule } from '#angular/common/http';
import { KeycloakService, KeycloakAngularModule } from 'keycloak-angular';
import { initializer } from './utils/app-init';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AuthenticationModule } from './core/auth/authentication.module';
import { NgxPermissionsModule } from 'ngx-permissions';
import { LayoutModule } from './content/layout/layout.module';
import { PartialsModule } from './content/partials/partials.module';
import { CoreModule } from './core/core.module';
import { AclService } from './core/services/acl.service';
import { LayoutConfigService } from './core/services/layout-config.service';
import { MenuConfigService } from './core/services/menu-config.service';
import { PageConfigService } from './core/services/page-config.service';
import { UserService } from './core/services/user.service';
import { UtilsService } from './core/services/utils.service';
import { ClassInitService } from './core/services/class-init.service';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { GestureConfig, MatProgressSpinnerModule } from '#angular/material';
import { OverlayModule } from '#angular/cdk/overlay';
import { MessengerService } from './core/services/messenger.service';
import { ClipboardService } from './core/services/clipboard.sevice';
import { PERFECT_SCROLLBAR_CONFIG, PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
import { LayoutConfigStorageService } from './core/services/layout-config-storage.service';
import { LogsService } from './core/services/logs.service';
import { QuickSearchService } from './core/services/quick-search.service';
import { SubheaderService } from './core/services/layout/subheader.service';
import { HeaderService } from './core/services/layout/header.service';
import { MenuHorizontalService } from './core/services/layout/menu-horizontal.service';
import { MenuAsideService } from './core/services/layout/menu-aside.service';
import { LayoutRefService } from './core/services/layout/layout-ref.service';
import { SplashScreenService } from './core/services/splash-screen.service';
import { DataTableService } from './core/services/datatable.service';
import 'hammerjs';
import { AppAuthGuardComponent } from './utils/keycloak/app-auth-guard/app-auth-guard.component';
import { KEYCLOAK_HTTP_PROVIDER } from './utils/keycloak/keycloak.http';
const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
// suppressScrollX: true
};
#NgModule({
declarations: [AppComponent, AppAuthGuardComponent],
imports: [
BrowserAnimationsModule,
BrowserModule,
AppRoutingModule,
HttpClientModule,
LayoutModule,
PartialsModule,
CoreModule,
OverlayModule,
AuthenticationModule,
NgxPermissionsModule.forRoot(),
NgbModule.forRoot(),
TranslateModule.forRoot(),
MatProgressSpinnerModule,
KeycloakAngularModule,
],
providers: [
AclService,
LayoutConfigService,
LayoutConfigStorageService,
LayoutRefService,
MenuConfigService,
PageConfigService,
UserService,
UtilsService,
ClassInitService,
MessengerService,
ClipboardService,
LogsService,
QuickSearchService,
DataTableService,
SplashScreenService,
KeycloakService,
KEYCLOAK_HTTP_PROVIDER,
{
provide: PERFECT_SCROLLBAR_CONFIG,
useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG
},
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
},
// template services
SubheaderService,
HeaderService,
MenuHorizontalService,
MenuAsideService,
{
provide: HAMMER_GESTURE_CONFIG,
useClass: GestureConfig
}
],
bootstrap: [AppComponent]
})
export class AppModule {
}
Check and add loadUserProfileAtStartUp: true, to the init config,
mine was like below, and It has resolved the issue for me,
export function initializer(keycloak: KeycloakService): () => Promise {
return (): Promise => {
return new Promise(async (resolve, reject) => {
try {
await keycloak.init({
config: {
url: environment.keycloak.issuer,
realm: environment.keycloak.realm,
clientId: environment.keycloak.clientId
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: 'check-sso',
checkLoginIframe: true
},
bearerExcludedUrls: []
});
resolve(1);
} catch (error) {
reject(error);
}
});
};
}