how can i access my env file from a nestjs module using passport js? - jwt

I am working on a small api using nestjs and passeport js
I have been trying to access the content of my env file, from within my auth module...but it's surpinsigly challenging...
import { userService } from 'src/user/services/user.service';
import { AuthService } from './auth.service';
import { PassportModule } from '#nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtModule } from '#nestjs/jwt';
import { JwtStrategy } from './jwt.strategy';
import { ConfigService } from '#nestjs/config';
#Module({
providers: [AuthService, userService, LocalStrategy, JwtStrategy],
imports: [
TypeOrmModule.forFeature([UserEntity, SpotEntity, SpotUserEntity]),
UserModule,
PassportModule,
JwtModule.register({
secret: ConfigService.get('JWT_SECRET'),
signOptions: { expiresIn: '600s' },
}),
],
exports: [AuthService],
})
export class AuthModule {}
Off course this cannot work because i am trying to utilize ConfigService.get() instead of this.configService.get()
I know i would need to instanciate configService in a constructor first, but modules do not have constructors, this is where i'm stuck at.

You can try registerAsync i.e
import { ConfigModule, ConfigService } from '#nestjs/config';
......
imports: [
PassportModule.register({
defaultStrategy: 'jwt',
}),
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => {
return {
signOptions: {
expiresIn: config.get<string>('JWT_EXPIRY'),
},
secret: config.get<string>('JWT_SECRET'),
};
},
inject: [ConfigService],
})
]
....

Related

'#ionic/storage-angular', data get delete after refresh

I am using angular in my ionic and I have followed everything based on this docs, so im using "#ionic/storage-angular", but my problem is when i refresh, data get deleted. Below is my code.
//app.module
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { HttpClientModule } from '#angular/common/http';
import { IonicStorageModule } from '#ionic/storage-angular';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
IonicStorageModule.forRoot(),
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule
],
providers: [
{
provide: RouteReuseStrategy,
useClass: IonicRouteStrategy,
},
],
bootstrap: [AppComponent]
})
export class AppModule {}
//storage.service
import { Injectable } from '#angular/core';
import { Storage } from '#ionic/storage-angular';
#Injectable({
providedIn: 'root'
})
export class StorageService {
private _storage: Storage | null = null;
constructor(private storage: Storage){
this.init();
}
async init() {
// https://github.com/ionic-team/ionic-storage
// If using, define drivers here: await this.storage.defineDriver(/*...*/);
const storage = await this.storage.create();
this._storage = storage;
}
public set(key: string, value: any) {
this._storage?.set(key, value);
}
public get(key){
return this._storage?.get(key);
}
public clear(){
this._storage.clear();
}
}
//this is how i used the service
await this.storageService.set('loginUser',{id: user.id,userName: user.first_name});

Deeplinks with Ionic / Capacitor

I'm trying to retrieve a request param from a deeplink to a Ionic 5 application using Deeplink plugin (authorization code provided by authorization server on successful authorization redirection).
Android intent filter seems correctly configured as the app is opening after successful authentication.
I keep having unmatched deeplinks with plugin_not_installed error.
app.module.ts:
import { HttpClientModule } from '#angular/common/http';
import { APP_INITIALIZER, NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { Deeplinks } from '#ionic-native/deeplinks/ngx';
import { SQLitePorter } from '#ionic-native/sqlite-porter/ngx';
import { SQLite } from '#ionic-native/sqlite/ngx';
import { Vibration } from '#ionic-native/vibration/ngx';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { IonicStorageModule } from '#ionic/storage';
import { ApiModule as NumeraApiModule } from '#lexi-clients/numera';
import { OidcUaaModule } from '#lexi/oidc-uaa';
import { AuthModule, OidcConfigService } from 'angular-auth-oidc-client';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SettingsService } from './settings/settings.service';
export function loadSettings(config: SettingsService) {
return () => config.load();
}
export function configureAuth(oidcConfigService: OidcConfigService) {
return () => oidcConfigService.withConfig(environment.authentication.angularAuthOidcClient);
}
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
AuthModule.forRoot(),
BrowserModule,
HttpClientModule,
IonicModule.forRoot(),
IonicStorageModule.forRoot(),
NumeraApiModule,
OidcUaaModule,
AppRoutingModule,
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: loadSettings,
deps: [SettingsService],
multi: true,
},
{
provide: APP_INITIALIZER,
useFactory: configureAuth,
deps: [OidcConfigService],
multi: true,
},
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
Deeplinks,
OidcConfigService,
SQLite,
SQLitePorter,
Vibration,
],
bootstrap: [AppComponent],
})
export class AppModule {}
app.component.ts:
import { AfterViewInit, Component, NgZone, OnDestroy, OnInit } from '#angular/core';
import { NavigationEnd, Router } from '#angular/router';
import { App, Plugins, StatusBarStyle } from '#capacitor/core';
import { AppCenterCrashes } from '#ionic-native/app-center-crashes';
import { Deeplinks } from '#ionic-native/deeplinks/ngx';
import { NavController, Platform } from '#ionic/angular';
import { LexiUser, UaaService } from '#lexi/oidc-uaa';
import { Observable, Subscription } from 'rxjs';
import { SettingsPage } from './settings/settings.page';
import { SettingsService } from './settings/settings.service';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent implements AfterViewInit, OnInit, OnDestroy {
constructor(
private platform: Platform,
private router: Router,
private idService: UaaService,
private settings: SettingsService,
private navController: NavController,
private deeplinks: Deeplinks,
private zone: NgZone
) {
this.platform.ready().then(async () => {
if (this.platform.is('mobile')) {
const { SplashScreen, StatusBar } = Plugins;
StatusBar.setStyle({ style: StatusBarStyle.Light });
SplashScreen.hide();
}
});
}
ngAfterViewInit() {
if (this.platform.is('mobile')) {
this.deeplinks.routeWithNavController(this.navController, { 'login-callback': SettingsPage }).subscribe(
(match) => {
console.log('Successfully matched route', match);
// Create our internal Router path by hand
const internalPath = '/settings';
// Run the navigation in the Angular zone
this.zone.run(() => {
this.router.navigateByUrl(internalPath);
});
},
(nomatch) => {
// nomatch.$link - the full link data
console.error("Got a deeplink that didn't match", nomatch);
}
);
}
}
}
I got it. My Ionic project is a module in an Angular multi-module project and plugin npm dependencies where added to root package.json.
Moving all Ionic-native related dependencies to package.json in Ionic project folder and running ionic cap sync again solved my problem.
Now the question is How to properly configure a Ionic module in an Angular mono-repo (aka multi-module project)?

Nest JS, Mongoose: Inject service into model

I'm having a problem with Nest Js and mongoose, Im trying to make a seed for my database,
And the main problem I'm having is I cannot import service from my module, into other module.
And it constantly gives me error:
Nest can't resolve dependencies of the CategoryModel (?). Please make sure that the argument at index [0] is available in the MongooseModule context.
the main thing I'm trying to do is to create seed for my categories.
Here is my Category Module:
import { Module } from '#nestjs/common';
import { CategoryController } from './category.controller';
import { CategoryService } from './category.service';
import { MongooseModule } from '#nestjs/mongoose';
import { CategorySchema } from 'src/models/category.schema';
#Module({
imports: [MongooseModule.forFeature([{ name: 'Category', schema: CategorySchema }])],
controllers: [CategoryController],
providers: [CategoryService]
})
export class CategoryModule {}
My Category service:
import { Model } from 'mongoose';
import { Injectable, Inject } from '#nestjs/common';
import { CategoryInterface } from '../interfaces/category.interface';
import { InjectModel } from '#nestjs/mongoose';
#Injectable()
export class CategoryService {
constructor(#InjectModel('Category') private categoryModel: Model<CategoryInterface>) {}
async create(category){
const createdQuestion = new this.categoryModel(category);
return createdQuestion.save();
}
async getMainCategories() {
return this.categoryModel.find( { parent: null } );
}
}
My Category Controller:
import { Controller, Post, Get, Body, HttpCode } from '#nestjs/common';
import { CategoryService } from './category.service';
#Controller('category')
export class CategoryController {
constructor(private categoryService: CategoryService) { }
#Post()
#HttpCode(204)
async createCategory(#Body() category) {
console.log('evo je kategorija ', category);
const data = await this.categoryService.create(category);
}
#Get('/main')
async getAllCategories() {
const data = await this.categoryService.getMainCategories();
return data;
}
}
My Seeder module where I'm having provider that seed database:
import { Module } from '#nestjs/common';
import { Seeder } from './seeder';
#Module({
providers: [Seeder],
})
export class SeederModule {}
and my seeder.ts
import { Injectable } from '#nestjs/common';
import { CategoryService } from 'src/category/category.service';
#Injectable()
export class Seeder {
constructor(private categoryService: CategoryService) { }
async seed() {
}
async categories() {
// const data = await this.categoryService.createMultiple(categories);
}
}
My App.module
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CategoryModule } from './category/category.module';
import { QuizModule } from './quiz/quiz.module';
import { ConfigModule } from '#nestjs/config';
import config from './config/config';
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017'),
ConfigModule.forRoot({ load: [config], isGlobal: true }),
CategoryModule,
QuizModule
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Category Model:
import * as mongoose from 'mongoose';
export const CategorySchema = new mongoose.Schema({
name: { type:String, required:true, unique: true },
slug: { type:String, required:true, unique: true },
});
And for some reason it is not working, even If I import whole
GitHub Repository of Project: https://github.com/HunterJS-bit/react-quiz-app
CategoryModule, or CategoryService into Seeder.module ??
Note: To reproduce error try running npm run seed from
server/package.json
Thanks for the help :)
You need to have the CategoryModule add exports: [CategoryService] to allow for other modules to import the module and make use to the CategoryService. This is how you share providers in NestJS. The, you need to add imports: [CategoryModule] to the SeederModule to allow the providers of the SeederModule to use the exports of the CategoryModule. Then, everything should load up just fine.

Angular 6 Shared Modules and Sharing Services

I'm having an issue with my Angular 6 app that I'm breaking up into smaller modules. Originally everything was imported into AppModule, and it worked just fine, but it was a giant file and testing was overly complicated.
The issue I'm having is basically creating a shared-module for a few commonly used services across the app. ng build runs fine so it seems to build alright, but when I serve the app I get the error that "ConfigService.foo()" is not a function! I'm obviously doing something wrong to group shared services into a shared module.
Here's some code:
SharedModule
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '#angular/common/http';
import { Injectable, OnInit, NgModule } from '#angular/core';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import * as $ from 'jquery';
import { PipeModule } from './pipes/pipes.module';
import { ConfigService } from "./config.service";
#NgModule({
imports: [
PipeModule
],
declarations: [
],
exports: [
PipeModule
],
providers: [
ConfigService
]
})
export class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
ConfigService, {
provide: ConfigService,
useValue: ConfigService
},
],
};
}
}
ConfigService
import {Injectable} from "#angular/core";
import {HttpClient, HttpHeaders, HttpParams, HttpResponse} from "#angular/common/http";
import {HttpObserve} from "#angular/common/http/src/client";
import {Observable, Subject, Observer, BehaviorSubject, throwError} from 'rxjs';
import {Config} from '../shared/config';
import { map, catchError} from 'rxjs/operators';
import * as _ from 'lodash';
#Injectable()
export class ConfigService {
constructor(private httpClient: HttpClient, private config: Config) {
this.config = new Config();
}
ngOnInit() { }
foo() {
console.log("Hack the planet!!! (confgurably)");
}
}
AppModule
import { BrowserModule } from '#angular/platform-browser';
import {APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, NgModule, PipeTransform} from '#angular/core';
import {HttpClient, HttpClientModule} from "#angular/common/http";
import {AppRoutingModule} from './app-routing.module';
import {FormsModule} from "#angular/forms";
import { AppComponent } from './app.component';
import { BannerComponent } from './banner/banner.component';
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
import { SearchComponent } from './search/search.component';
import { SharedModule } from './shared/shared.module';
#NgModule({
declarations: [
AppComponent,
BannerComponent,
BreadcrumbComponent,
SearchComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
AppRoutingModule,
SharedModule.forRoot()
],
providers: [
HttpClient
],
bootstrap: [AppComponent]
})
export class AppModule { }
What am I doing wrong with my Shared-Module and injectable services? For reference, I'm using Angularv6.
I just figured it out.
It turns out, when providing your own services in a module, you don't use
{ provide: ConfigService, useValue: ConfigService },
Instead, you simply list the services under providers in your exported module, like this:
export class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
ConfigService
],
};
}
}
Cheers!

Angular2 (typescript) - can't load ng2-restangular

I actually struggle to load ng2-restangular (from https://github.com/2muchcoffeecom/ng2-restangular) in a new project.
Here is my config:
(function (global) {
System.config({
paths: {
'npm:': 'node_modules/'
},
map: {
app: 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/router/upgrade': 'npm:#angular/router/bundles/router-upgrade.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
'#angular/upgrade': 'npm:#angular/upgrade/bundles/upgrade.umd.js',
'#angular/upgrade/static': 'npm:#angular/upgrade/bundles/upgrade-static.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'ng2-restangular': 'npm:ng2-restangular/dist/umd/ng2-restangular.js',
'lodash':'npm:lodash'
},
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
lodash: {
main: './index.js',
defaultExtension: 'js'
}
}
});
})(this);
app.module.ts:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { RestangularModule } from 'ng2-restangular';
#NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
// Importing RestangularModule and making default configs for restanglar
RestangularModule.forRoot((RestangularProvider) => {
RestangularProvider.setBaseUrl('http://0.0.0.0:3011/api/');
// RestangularProvider.setRestangularFields({
// id: "_id"
// });
}
)
],
bootstrap: [AppComponent]
})
export class AppModule { }
And app.component.ts:
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { Restangular } from 'ng2-restangular';
#Component({
selector: 'my-app',
template: '<h1>hello world</h1>'
})
export class AppComponent implements OnInit, AfterViewInit {
// If I remove this line...
constructor(private restangular: Restangular) {
}
ngOnInit(): void {
//...and this one, everything works fine.
this.restangular.all('Annotations').getList().toPromise().then(function(annotations) {
console.log(annotations);
});
}
ngAfterViewInit(): void {
}
}
When I add the constructor I got this error:
Error: Permission denied to access property "rejection"
in
zone.js (ligne 386, col. 13)
Any idea?
In my case, I had to import HttpModule in app.module.ts
ex:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { RestangularModule } from 'ng2-restangular';
import { HttpModule } from '#angular/http';
#NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
HttpModule,
// Importing RestangularModule and making default configs for restanglar
RestangularModule.forRoot((RestangularProvider) => {
RestangularProvider.setBaseUrl('http://0.0.0.0:3011/api/');
}
)
],
bootstrap: [AppComponent]
})
export class AppModule { }
and use the typescript compiler in systemjs.config.js:
(function (global) {
System.config({
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
paths: {
'npm:': 'node_modules/',
'ng2-restangular': 'node_modules/ng2-restangular/dist/esm/src'
},
map: {
app: 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/router/upgrade': 'npm:#angular/router/bundles/router-upgrade.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
'#angular/upgrade': 'npm:#angular/upgrade/bundles/upgrade.umd.js',
'#angular/upgrade/static': 'npm:#angular/upgrade/bundles/upgrade-static.umd.js',
// other libraries
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'typescript': 'npm:typescript/lib/typescript.js',
'ng2-restangular': 'ng2-restangular',
'rxjs': 'npm:rxjs',
'lodash': 'npm:lodash'
},
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
main: "./Rx.js",
defaultExtension: 'js'
},
lodash: {
main: './lodash.js',
defaultExtension: 'js'
},
'ng2-restangular': {
main: './index',
defaultExtension: 'js'
}
}
});
})(this);