How to make inrupt's authn library work with Vue/Pinia? (reactivity issue)

I’m developing a Solid App using Vue. Everything works roughly without issues, apart from the @inrupt/solid-client-authn-browser library.

For Vue, we would create a reactive object to the Session object, and use the values/fields of it. Due to the need to refresh (redirect) to log-in, I stored the object using Pinia store.

In principle, and in my tests, the reactive data should work without issues for nested data. However, if I try to use session.info.isLoggedIn (or any other fields in Session object), the reactivity disappears.
(See this repo if you want a MRE with example.)

In the end, I have to use some annoying tricks to make it work, namely listening to events and have my own reactive values for them (see handleRedirectAfterLogin() in my code). This basically requires me to duplicate every value I’m interested in.

Did anyone else run into this issue? How did you solve it? Or is this a bug that I’d better report to inrupt?

Looking at your code, I think the problem may be that you’re creating a Session object and you expect this to be updated by the library and trigger reactive changes in Pinia.

I’m also using Vue (although with Vuex, but I don’t think that’s important). But instead of relying on the object to be updated, I manually set the entire session object every time the authentication status is updated.

You can get the new session object in the result from calling the handleIncomingRedirect method.

3 Likes

Thanks, that’s good to know.

But instead of relying on the object to be updated, I manually set the entire session object every time the authentication status is updated.

Do you also happen to know the performance overhead of doing this? I presume Pinia/Vue will take care of this, but because it didn’t pick up the update in the first instance…

I’m pretty sure it’s negligible, specially given that it only happens once. It’d be a different story if you did it inside a loop or something, but even then I don’t think it’d be something to worry about.

1 Like

I tried it today, but got type error.

Type “ISessionInfo” is missing from type“{ readonly info: { isLoggedIn: boolean; webId?: string | undefined; clientAppId?: string | undefined; sessionId: string; expirationDate?: number | undefined; }; login: (options: ILoginInputOptions) => Promise<...>; ... 22 more ...; eventNames: () => (string | symbol)[]; }” of the following properties: info, login, fetch, logout and 21 more. ts(2740)

It seems Session has more than ISessionInfo… Is it safe to use it as a Session object? The document didn’t say anything.

I’m not familiar with Vue and can’t see the code that’s leading to that error message, but it sounds like your passing session to something that expects session.info. (Because the error message says that ISessionInfo is missing from a type that includes a .info property.)

Ah, thanks. That’s the key observation. It seems indeed the returned value from handleIncomingRedirect is something for session.info, rather than session.

So, the original question persists… session’s reactivity is lost somehow. Only having ISessionInfo is not sufficient…

Why do you need a Session object? I think ISessionInfo already has all the information you need in your app, doesn’t it? It seems like the only thing that Session has are some methods, but you can import those methods directly from the library and use them however you like.

I guess it’d be a different story if you have more than one session in your app, but that hasn’t been the case for my apps.