wi3land / ionic-appauth

Intergration for OpenId/AppAuth-JS into Ionic V3/4/5
MIT License
93 stars 74 forks source link

Independent observers have been replaced by Rxjs this will be removed in a future release please use $ suffixed observers in future #65

Open nirajhinge opened 3 years ago

nirajhinge commented 3 years ago

We are using the package with Ionic5, Vue3 and Capacitor3 and before we upgraded from Capacitor2 to Capacitor3, everything worked as expected.

After upgrading to Capacitor3, we got some issues and once 0.8.0 was released, we upgraded the package but looks like there are a few deprecated method with the following comment:

Independent observers have been replaced by Rxjs this will be removed in a future release please use $ suffixed observers in future

Our current code looks like this:

setup() {
    const router = useRouter();
    let authObserver = Auth.Instance.addActionListener((action) => postCallback(action));

    onMounted(() => {
      Auth.Instance.authorizationCallback(window.location.origin + router.currentRoute.value.fullPath)
    })

    onUnmounted(() => {
      Auth.Instance.removeActionObserver(authObserver);
    });

    function postCallback(action: IAuthAction) {

      if (action.action === AuthActions.SignInSuccess) {
        // router.replace('/');
      }
      //
      if (action.action === AuthActions.SignInFailed) {
        // console.log('Failed');
      }
    }

    return {router};
  }

We are now getting warning with the above message but the docs or examples or code doesn't seem to be updated yet to show how/which methods should be used instead. It would be great if there would be some examples on how to fix this as we are now getting errors like this after the update:

Checking to see if there is an authorization response to be delivered.
Notifier is not present on AuthorizationRequest handler. No delivery of result will be possible

Thanks

wi3land commented 3 years ago

Hi Sorry, Just going through and updating demos now. if you go to the new vue demo. It will show you what to implement.

Essentially there are now five new observerables. -isAuthenticated$ - shows if user is authenticated -user$ - displays info returned from user endpoint -events$ - the existing actions such as sign in success -initComplete$ - true once a token load from storage has occured -token$ - the token response if available

nirajhinge commented 3 years ago

@wi3land That's fantastic. I will give that a go and let you know. Thanks.

wi3land commented 3 years ago

Just to say I am no Vue expert I only learnt what I did in the solution this morning so if you have any notes that would be great as a vue developer.

nirajhinge commented 3 years ago

@wi3land I had a go at the vue example and while it could be upgraded to vue3 specific api, I definitely could follow through it to integrate it in my app. It has worked on the web version but for some reason when I tried on the iOS emulator, it looks like appUrlOpen event is never fired so the following does not work at all:

if (isPlatform('capacitor')) {
      App.addListener('appUrlOpen', (data: any) => {
        if (data.url !== undefined) {
          if (data.url.indexOf(authService.authConfig.redirect_url) === 0) {
            authService.authorizationCallback(data.url)
          } else {
            authService.endSessionCallback()
          }
        }
      })
    }

I get the following error when I click on Login button despite the authConfig being all set properly:

{"action":"Sign In Failed","error":"Unable To Obtain Server Configuration"}

Looks like this was an issue before as well seeing an issue here as well as another similar issue here but I am already on Capacitor 3 so wondering if I have to do anything else here?

wi3land commented 3 years ago

For native deep links you need to add some extra items into the ios and android projects. This guide will show you what needs to be added.

wi3land commented 2 years ago

Hi @nirajhinge have you been able to get the solution working on ios

nirajhinge commented 2 years ago

@wi3land I have had troubles setting up the deep links but will let you know as soon as that is resolved and I can test it. It has worked as expected on the web platform otherwise.

nirajhinge commented 2 years ago

@wi3land So I have had a go at this again and this is not an issue with the deep links since even fixing that doesn't work. Upon further investigation, I have found out that the in-app browser simply is not firing from the plugin when I click Sign In in the demo app in iOS and android emulator. This is only happening after updating from 0.7.4 to the latest version.

I also checked if the listeners were registered correctly and they are all fine as well.

I have attached a screenshot with the error both on iOS and android devices. On clicking Open In App Browser, it works as expected and opens an in app. I was hoping for the same behaviour - open the in-app browser (I have tried it in an app where the server configuration is correct as well - it worked with the previous version of this plugin) but it simply silently fails.

Not sure what exactly might be the reason but this is not just happening on the the vue demo but also on angular-capacitor demo as well.

Screenshot 2021-08-09 at 16 49 38
nirajhinge commented 2 years ago

@wi3land Some more info in case you have a chance to look at it. I decided to use the Capacitor Browser directly for the sign in and it does open the browser as expected with a code like this:

Browser.open({ url:
 'https://foo.bar/Account/Login?redirect_uri%3DmyApp%3A%2F%2Fauth%2Fcallback%26client_id%3DAppId%26response_type%3Dcode%26state%3D4pFSok5TCZ%26scope%3Dscope%26code_challenge%3DJ9hwwLRVZ_dwHH7IlzFCeBe_0i_yYBKB3YC7FOZDmbY%26code_challenge_method%3DS256'
 });

But the issue is that without using Auth.Instance.signIn() method, even when the correct response is returned, the sign in fails with the SignInFailed error when listening to the IAuthAction in App.vue setup:

 Auth.Instance.events$.subscribe((iAuthAction: IAuthAction) => {
      console.log(iAuthAction)

It definitely looks like there is some issues with the in-app browser not loading on the devices after the update as it was working fine until updating to Capacitor 3 and ionic-appauth 0.8.

mraible commented 2 years ago

I've integrated the latest v0.8.4 into OktaDev Schematics and got everything to work. See tab1.page.ts for more info. In short, this should work:

events$ = this.auth.events$;
sub: Subscription;
action: IAuthAction;

constructor(private navCtrl: NavController, private auth: AuthService) {
}

ngOnInit() {
  this.sub = this.auth.events$.subscribe((action) => this.onAction(action));
}

ngOnDestroy() {
  this.sub.unsubscribe();
}

private onAction(action: IAuthAction) {
  if (action.action === AuthActions.LoadTokenFromStorageFailed ||
    action.action === AuthActions.SignInFailed ||
    action.action === AuthActions.SignOutSuccess) {
    delete this.action;
  } else {
    this.action = action;
  }
}
nirajhinge commented 2 years ago

@mraible Thanks for the response. That looks like Angular and I am using Vue. Looking at what you have done and our own research, it looks like for some reason the Auth Instance was not getting instantiated and the whole thing was silently failing when trying to sign in. I am currently researching a fix and will update the comment once I confirm it.

wi3land commented 2 years ago

The Unable to obtain configuration error is occurs when the app is having issues connecting to your identity provider normally. It is thrown if a 404 is returned from the discovery url .well-known/openid-configuriation.

I have never worked with vue before and I don't know if i am not initialising the service correctly. I need to to be introduced at the earliest point in the vue lifecycle to allow for the capacitor app listener to work.

gklasen commented 2 years ago

@nirajhinge any news on that missing Auth instance?