How can I return UUID using RabbitMQ - rabbitmq

I would like to return the UUID(v4) created for each request in nestjs as a response to the request.
I want to return the UUID(v4) that nestjs creates for each request as the response to the request.
However, I am using rabbitmq.
Is there any other way to return the UUID after going through rabbitmq for each request?
With this method, I am creating a connection for each request.
I want to create the connection only once after nestjs is started.
Also, any other method using other libraries would be good.
import { Controller, Get } from '#nestjs/common';
import { v4 as uuidv4 } from 'uuid';
#Controller('cats')
export class CatsController {
#Get()
findAll(): string {
const sequence = uuidv4(); // I want to return this.
return 'This action returns all cats';
}
}
...
await channel.consume(queueName, async (data: any) => {
if (queueName === 'testQueue') {
// do something.
}
});

Related

How can we access decorator from a service class in NestJS

I am new in NestJS and trying to do auth system. I was able to do. So here is what I am doing to get access to auth.
In my controller I have
#Get('/user')
async getUser(#AuthUser() token: string) : Promise<Object> {
return this.authService.getUser(token)
return token
}
Here I am passing a AuthUser decorator I want to avoid passing in controllers.
In the authService.getUser method I have something like this
async getUser(token: string): Promise<Object> {
try {
const user = await this.jwtService.verifyAsync(token)
return user
} catch (error) {
return false
}
}
and my decorator looks like this
import { createParamDecorator, ExecutionContext } from '#nestjs/common';
export const AuthUser = createParamDecorator(
(data = 'u_ses', ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return data ? request.cookies?.[data] : request.cookies;
},
);
I don't like code. If I need to know the user id from a service class or anywhere I would need to pass the token and to get token I need use #AuthUser() token: string)
So I want to do something like this
this.authService.getUser(), here I don't want to pass token or anything and should be able to access this getUser method from anywhere. Since it's a service class, I can inject and use it but I won't have the token.
I tried injecting the decorator inside the service class, but this doesn't work.
One best solution I would prefer is to use the JWT things inside the decorator, so I don't need the service class' method :)
I am looking for a nicer solutions from you :)
Thank you.
Nestjs has NestMiddleware. Here, you can authorize before access to controller like this:
import { Injectable, NestMiddleware, UnauthorizedException } from '#nestjs/common';
import { Request, Response, NextFunction } from 'express';
#Injectable()
export class AuthenticationMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const headerAuthentication = req.headers.authorization;
if(!headerAuthentication) throw new UnauthorizedException('Authorization failed!');
const token = req.headers.authorization.split(' ')[1];
if(token) {
next();
}else {
throw new UnauthorizedException('Authorization failed!');
}
}
}
and in AppModule implement it
configure(consumer: MiddlewareConsumer) {
consumer.apply(AuthenticationMiddleware).forRoutes('/');
}
}

i18n-backend with oauth2 authorization in spartacus

We want to use a backend for i18n in spartacus. Unfortunately this backend needs an oauth2 authentication but spartacus does not send a bearer token when trying to access this webservice endpoint and we get a 401 error. Is there anything we can do?
Right now we try to solve this problem in this way:
What we need to have is implemented in ClientTokenInterceptor, so we adapted this interceptor, changed the if-clause a little bit so it fits to the backend-url for this webservices and provide the interceptor via app.module.ts which works so far. Unfortunately calling this.authService.getClientToken() in our Interceptor returns no token.
constructor(
private authService: AuthService,
private occEndpoints: OccEndpointsService
) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return this.getClientToken(request).pipe(
take(1),
switchMap((token: ClientToken) => {
if (
token &&
request.url.includes("i18n")
) {
request = request.clone({
setHeaders: {
Authorization: `${token.token_type} ${token.access_token}`,
},
});
}
return next.handle(request);
})
);
}
private getClientToken(request: HttpRequest<any>): Observable<ClientToken> {
if (
InterceptorUtil.getInterceptorParam(USE_CLIENT_TOKEN, request.headers)
) {
return this.authService.getClientToken();
}
return of(null);
}
What do we miss?
Actually there are couple of things not needed in your solution.
I pasted below what I did instead and tested that it is working correctly (and you can see authorization data in the translation files requests).
First issue:
InterceptorUtil.getInterceptorParam(USE_CLIENT_TOKEN, request.headers) you don't need to check that. If you always need the auth data for translation requests just use return this.authService.getClientToken();
Second issue:
In intercept method you didn't cover cases for any other request than translation. Because of that the request for the client token would hang here, because it would wait for token and so on. If you add option for any other case than i18n it starts working as you intend.
Working solution:
#Injectable({ providedIn: 'root' })
export class TranslationsInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (request?.url?.includes('i18n')) {
return this.getClientToken().pipe(
take(1),
switchMap((token: ClientToken) => {
if (token) {
request = request.clone({
setHeaders: {
Authorization: `${token.token_type} ${token.access_token}`,
},
});
}
return next.handle(request);
})
);
} else {
return next.handle(request);
}
}
private getClientToken(): Observable<ClientToken> {
return this.authService.getClientToken();
}
}

Http post and get request in angular 6

In angular 5.2.x for http get and post I had this code:
post(url: string, model: any): Observable<boolean> {
return this.http.post(url, model)
.map(response => response)
.do(data => console.log(url + ': ' + JSON.stringify(data)))
.catch(err => this.handleError(err));
}
get(url: string): Observable<any> {
return this.http.get(url)
.map(response => response)
.do(data =>
console.log(url + ': ' + JSON.stringify(data))
)
.catch((error: any) => Observable.throw(this.handleError(error)));
}
In angular 6 it doesn't work.
How can we make an HTTP post or get request?
Update :
In angular 7, they are the same as 6
In angular 6
the complete answer found in live example
/** POST: add a new hero to the database */
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions)
.pipe(
catchError(this.handleError('addHero', hero))
);
}
/** GET heroes from the server */
getHeroes (): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
catchError(this.handleError('getHeroes', []))
);
}
it's because of pipeable/lettable operators which now angular is able to use tree-shakable and remove unused imports and optimize the app
some rxjs functions are changed
do -> tap
catch -> catchError
switch -> switchAll
finally -> finalize
more in MIGRATION
and Import paths
For JavaScript developers, the general rule is as follows:
rxjs: Creation methods, types, schedulers and utilities
import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent } from 'rxjs';
rxjs/operators: All pipeable operators:
import { map, filter, scan } from 'rxjs/operators';
rxjs/webSocket: The web socket subject implementation
import { webSocket } from 'rxjs/webSocket';
rxjs/ajax: The Rx ajax implementation
import { ajax } from 'rxjs/ajax';
rxjs/testing: The testing utilities
import { TestScheduler } from 'rxjs/testing';
and for backward compatability you can use rxjs-compat
You can do a post/get using a library which allows you to use HttpClient with strongly-typed callbacks.
The data and the error are available directly via these callbacks.
The library is called angular-extended-http-client.
angular-extended-http-client library on GitHub
angular-extended-http-client library on NPM
Very easy to use.
Traditional approach
In the traditional approach you return Observable<HttpResponse<T>> from Service API. This is tied to HttpResponse.
With this approach you have to use .subscribe(x => ...) in the rest of your code.
This creates a tight coupling between the http layer and the rest of your code.
Strongly-typed callback approach
You only deal with your Models in these strongly-typed callbacks.
Hence, The rest of your code only knows about your Models.
Sample usage
The strongly-typed callbacks are
Success:
IObservable<T>
IObservableHttpResponse
IObservableHttpCustomResponse<T>
Failure:
IObservableError<TError>
IObservableHttpError
IObservableHttpCustomError<TError>
Add package to your project and in your app module
import { HttpClientExtModule } from 'angular-extended-http-client';
and in the #NgModule imports
imports: [
.
.
.
HttpClientExtModule
],
Your Models
export class SearchModel {
code: string;
}
//Normal response returned by the API.
export class RacingResponse {
result: RacingItem[];
}
//Custom exception thrown by the API.
export class APIException {
className: string;
}
Your Service
In your Service, you just create params with these callback types.
Then, pass them on to the HttpClientExt's get method.
import { Injectable, Inject } from '#angular/core'
import { SearchModel, RacingResponse, APIException } from '../models/models'
import { HttpClientExt, IObservable, IObservableError, ResponseType, ErrorType } from 'angular-extended-http-client';
.
.
#Injectable()
export class RacingService {
//Inject HttpClientExt component.
constructor(private client: HttpClientExt, #Inject(APP_CONFIG) private config: AppConfig) {
}
//Declare params of type IObservable<T> and IObservableError<TError>.
//These are the success and failure callbacks.
//The success callback will return the response objects returned by the underlying HttpClient call.
//The failure callback will return the error objects returned by the underlying HttpClient call.
searchRaceInfo(model: SearchModel, success: IObservable<RacingResponse>, failure?: IObservableError<APIException>) {
let url = this.config.apiEndpoint;
this.client.post<SearchModel, RacingResponse>(url, model,
ResponseType.IObservable, success,
ErrorType.IObservableError, failure);
}
}
Your Component
In your Component, your Service is injected and the searchRaceInfo API called as shown below.
search() {
this.service.searchRaceInfo(this.searchModel, response => this.result = response.result,
error => this.errorMsg = error.className);
}
Both, response and error returned in the callbacks are strongly typed. Eg. response is type RacingResponse and error is APIException.
For reading full response in Angular you should add the observe option:
{ observe: 'response' }
return this.http.get(`${environment.serverUrl}/api/posts/${postId}/comments/?page=${page}&size=${size}`, { observe: 'response' });

How to Create Aurelia Services without Redundant Header Configuration?

I'm currently working on a project using Aurelia as the front-end framework, and I'm wondering if there's a more eloquent and less redundant way to set the request header in my API services. The following is an example.
In this Post service, I have created a configureHeaders method that I'm calling prior to every API call because, otherwise, I run into the case where the web token has changed but the request header isn't updated. While creating this configureHeaders method is a functional workaround, I have to do it for each of my services, and it's feeling very redundant.
Is there a way to configure the request header application-wide so that I don't have to create a configureHeaders method for each service and call it for each request?
import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-http-client';
import environment from 'environment';
#inject(HttpClient)
export class Post {
constructor(http) {
this.http = http;
}
configureHeaders() {
this.token = window.localStorage.getItem('token') || null;
this.http = this.http
.configure(x => {
x.withBaseUrl(environment.serverBaseURL);
x.withHeader('Authorization', `Bearer ${this.token}`);
});
}
getPosts() {
this.configureHeaders();
return this.http.get('post')
.then(posts => {
return JSON.parse(posts.response);
});
}
}
As R.Richards commented, Aurelia's HttpClient Interceptor is what you're after.
Here's a class example - as opposed to object with anonymous functions
1.) Declare the interceptor
import {Interceptor, HttpResponseMessage, RequestMessage} from 'aurelia-http-client'
export class CustomInterceptor implements Interceptor {
request(request: RequestMessage): RequestMessage {
//Do request interceptor here
return request;
}
response(response: HttpResponseMessage): HttpResponseMessage{
//Do response interception here
return response;
}
}
2.) Register the interceptor as part of your default http client within your main.js
import {CustomInterceptor} from 'path/to/custom-interceptor'
...
...
http.configure(config => {
//config stuff here
).withInterceptor(new CustomInterceptor())
This should suit your eloquence!

Angular2: canActivate

Currently I want to implement canActivate function, everything I want is to send a request to server each time page requested and get true/false in a json response in order to understand is user authenticated and permitted to review current page.
And it seems that I completely stuck with observable and promise objects, which is new for me, what is what I have so far.
import { Injectable } from '#angular/core';
import {CanActivate, Router} from '#angular/router';
import { Http, Response } from '#angular/http';
import {Observable, Observer, Subject} from "rxjs/Rx";
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private http: Http) {}
canActivate() {
if (this.isAuthenticated()) {
return true;
} {
this.router.navigate(['404']);
return false;
}
}
isAuthenticated() : Observable<boolean> {
var subject = new Subject<boolean>();
this.http.get("/index.php?module=Api&action=IsAuthenticated")
.map((res : Response) => res.json())
.subscribe(res => {
console.log("next: returning true");
subject.next(true);
}, (res) => {
console.log("next: returning false");
subject.next(false);
});
return subject.asObservable().first();
}
}
A few changes
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private http: Http) {}
canActivate() {
return this.isAuthenticated().first(); // not sure if `.first() is still necessary
}
isAuthenticated() : Observable<boolean> {
return this.http.get("/index.php?module=Api&action=IsAuthenticated")
.map((res : Response) => res.json())
.catch(err => return Observable.of(false))
.map(res => {
return true
});
}
}
If isAuthenticated() does some async execution, we don't get true or false back, we get an Observable that emits a true or false value eventually
What we do is to return the observable we get from isAuthenticated()
In isAuthenticated with return the observable we get fromthis.http.get()and transform the emitted event. It seems the response from the server (res.json()) is not used. Therefore we usecatch()to returnfalsein case of an error andtrue` otherwise.
Because the response from the server is not used .map((res : Response) => res.json()) could be omitted, except this is where you expect an error from that should case false to be returned.
Also your production code might look different and require the response to be processed.
We don't subscribe anywhere, because this is what the router is doing when an Observable is returned from canActivate and if we call subscribe() we get a Subscription instead of an Observable.
canActivate can return either Observable<boolean>, Promise<boolean> or boolean.
As you are depending on asynchronous checking you cannot return a boolean.
It however looks like you could just simply do
canActivate(): Observable<boolean> {
return this.isAuthenticated();
}
I'm no expert on Observable yet, but it would also be easy for you to chain on a call to redirect if you where not authorised.
Here is the solution that works for me:
canActivate() {
return this.http.get("/index.php?module=Api&action=IsAuthenticated")
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}