abacritt / angularx-social-login

Social login and authentication module for Angular 17
630 stars 388 forks source link

Add ability to disable Google one-tap from SocialAuthService #768

Open cdietz7 opened 1 month ago

cdietz7 commented 1 month ago

Use Case: As I'm introducing Google Sign In to our application, there could be bugs or issues present with the feature, so I'd like to introduce a feature flag for testing the sign in before presenting to the public. Or, maybe I need to temporarily disable the Google Sign In but I don't want to rip out all the "pipe" and would like to simply have a one-liner set-to-false.

Let's say, I want this page to display the login: example.com/login?google=true And this page hides it: example.com/login

Under the hood, the page routes to the same component.

What I'm observing: (Assuming I've done all the initial configuration steps) As soon as I add the SocialAuthService to my component, the Google One-tap window appears in the upper-right, prompting the user to log into Google. This happens even if I've commented-out my element and my SocialAuthService.authState Observable subscription code; in other words, I've added the service class to my constructor and nothing else.

Desired behavior: Assuming default behavior would be to initialize Google and show the one-tap, I would like to conditionally disable the one-tap via the query string parameter or other conditional so that if the conditional is true, the one-tap (and probably the button too) will display on the page. If the conditional is false, one-tap (and the button, probably by an *ngIf or the service class behavior) will disable the one-tap and Google login.

I suppose another way of putting my issue and question is--how can I conditionally enable/disable the Google login by means of a query string on a specific component, with the smallest code footprint possible?

One workaround I've thought of may be to create a separate component to place the SocialAuthService in a child component, subscribe to authState in that component, and emit all values in the component's output. Then, have the parent *ngIf the child component based on the query string or other conditional, thus having the SocialAuthService conditionally load as well. I'm not 100% a fan because I feel it adds business logic to a child component, but I could be wrong.

Asking for second opinions or a potential feature to fix this, thanks!

cdietz7 commented 1 month ago

Actually, I just tried the workaround and it works nicely.

Child component .ts:

import { SocialAuthService, SocialUser } from '@abacritt/angularx-social-login';
import { Component, EventEmitter, Output } from '@angular/core';
import { Observable } from 'rxjs';

@Component({
  selector: 'pbos-auth-google',
  templateUrl: './google.component.html',
  styleUrls: ['./google.component.scss']
})
export class GoogleComponent {

  @Output() initAuthState: EventEmitter<Observable<SocialUser>> = new EventEmitter();

  constructor(
    // Note: adding SocialAuthService to the constructor automatically enables the Google one-tap sign-in.
    private socialAuth: SocialAuthService,
  ) {}

  ngOnInit() {
    // Emitting the authState observable directly
    this.initAuthState.emit(this.socialAuth.authState);
  }

}

Child component HTML:

<asl-google-signin-button type="standard" size="medium"></asl-google-signin-button>

Parent component ts snippet

//...

  protected authStateSubscription?: Subscription;

//...

  onInitAuthState(observable: Observable<SocialUser>) {
    if (this.authStateSubscription) {
      return;
    }

    this.authStateSubscription = observable.pipe(
      // ## Any further API calls can go in here
    ).subscribe((profileResponse) => {
      // ## In my case, I called for a User Profile in the pipe() and the result's in profileResponse.
    });
  }

//...

  ngOnDestroy(): void {
    this.authStateSubscription?.unsubscribe();
  }

//...

Parent component HTML

...
<pbos-auth-google *ngIf="isGoogleActive" class="center" (initAuthState)="onInitAuthState($event)"></pbos-auth-google>
...

Still open to second opinions if any though.