Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom NbAuthStrategy getting result from async call #2388

Open
pellyadolfo opened this issue May 28, 2020 · 2 comments
Open

Custom NbAuthStrategy getting result from async call #2388

pellyadolfo opened this issue May 28, 2020 · 2 comments

Comments

@pellyadolfo
Copy link

I am creating my own authentication method. I have extended NbAuthStrategy and implemented method authenticate as shown below

@Injectable()
export class MyAuthStrategy extends NbAuthStrategy {
     ...
     authenticate(user: UserData): Observable<NbAuthResult> {
          ...
          this.userService.getUser(userId, function(user: IUser) {
              console.log("called back" + user); ////// ?????
          });
          ...
     }
     ...
}

the method is expected to return a Observable object.

When I do a memory authentication it works great, no issues.

The problem comes when I try to authenticate on an AWS Lambda by doing an async call. As the response is async, I cannot return Observable so I find this authentication mechanism only works for memory or synchronous calls.

How can I authenticate when validation is done on an async call?

@piotrbrzuska
Copy link
Contributor

Try extend NbAuthStrategy:

authenticate(data?: any): Observable<NbAuthResult> {
    const module = 'login';
    const method = this.getOption(`${module}.method`);
    const url = this.getActionEndpoint(module);
    const requireValidToken = this.getOption(`${module}.requireValidToken`);
    return this.http.request(method, url, { body: data, observe: 'response', withCredentials: true })
      .pipe(
        map((res) => {
          if (this.getOption(`${module}.alwaysFail`)) {
            throw this.createFailResponse(data);
          }
          return res;
        }),
        map((res) => {
          return new NbAuthResult(
            true,
            res,
            this.getOption(`${module}.redirect.success`),
            [],
            this.getOption('messages.getter')(module, res, this.options),
            this.createToken(this.getOption('token.getter')(module, res, this.options), requireValidToken));
        }),
        catchError((res) => {
          return this.handleResponseError(res, module);
        }),
      );
  }

@pellyadolfo
Copy link
Author

pellyadolfo commented Jul 25, 2020

I got his working with your help

Basically:

  1. return a Promise with the user from the AWS Lambda
  2. wrap it an async await method so it returns another Promise
  3. convert the Promise to Observable
  4. pipe/map the Observable to return the Observable< NbAuthResult > object

authenticate(user: UserData): Observable< NbAuthResult > {

   const userPromise: Promise<IUser> = this.userPromiseService.getUserPromise(user.schema, user.username);
   const userObservableDeferred3: Observable<NbAuthResult> = defer(() => userPromise)
     .pipe(
        map((res) => {

           return new NbAuthResult(
              true,
              null,
              '/pages/user-account',
             'Welcome',
           );

        }),
     );

   return userObservableDeferred3;
}

async getUserPromise(schema: string, username: string): Promise< IUser > {

  // invoke lambda
  const params = {
    ...
  };
  const result = await (this.getAWSLambda().invoke(params).promise());

  // get resulting user
  const payload = result.Payload;
  const arrayss = JSON.parse(payload);
  const array = JSON.parse(arrayss);
  const item = array[0];
  return < IUser >item;
}

https://stackoverflow.com/questions/62027394/custom-nbauthstrategy-getting-result-from-async-call/62781232#62781232

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants