Skip to content

Commit

Permalink
fix: iOS login blocked (#1295)
Browse files Browse the repository at this point in the history
# Motivation

Long story short: on iOS, click on the "Login" have no effect 馃憠 user cannot sign-in on iOS with the current development version which uses agent-js `v0.13.x` (mainnet uses currently `v0.12.x` which is fine).

More details and context in related agent-js issue dfinity/agent-js#618

# Changes

- keep `authClient` object in memory to not call `authClient.create` before `authClient.login` - i.e. avoid any async callback within the same function that should ultimately call `window.open`
  • Loading branch information
peterpeterparker committed Aug 31, 2022
1 parent b7ac749 commit b699fd5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dfx.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"dfx": "0.11.1",
"dfx": "0.11.2",
"canisters": {
"nns-governance": {
"type": "custom",
Expand Down
41 changes: 25 additions & 16 deletions frontend/src/lib/stores/auth.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export interface AuthStore {
identity: Identity | undefined | null;
}

// We have to keep the authClient object in memory because calling the `authClient.login` feature should be triggered by a user interaction without any async callbacks call before calling `window.open` to open II
// @see agent-js issue [#618](https://github.com/dfinity/agent-js/pull/618)
let authClient: AuthClient | undefined;

/**
* A store to handle authentication and the identity of the user.
*
Expand Down Expand Up @@ -38,7 +42,7 @@ const initAuthStore = () => {
subscribe,

sync: async () => {
const authClient: AuthClient = await createAuthClient();
authClient = authClient ?? (await createAuthClient());
const isAuthenticated: boolean = await authClient.isAuthenticated();

set({
Expand All @@ -48,27 +52,32 @@ const initAuthStore = () => {

signIn: () =>
new Promise<void>((resolve, reject) => {
createAuthClient().then((authClient: AuthClient) => {
authClient.login({
identityProvider: IDENTITY_SERVICE_URL,
maxTimeToLive: AUTH_SESSION_DURATION,
onSuccess: () => {
update((state: AuthStore) => ({
...state,
identity: authClient.getIdentity(),
}));
// This is unlikely to happen because above `sync` function of the store is the main function that is called before any components of the UI is rendered
// @see `Guard.svelte`
if (authClient === undefined) {
reject();
return;
}

authClient?.login({
identityProvider: IDENTITY_SERVICE_URL,
maxTimeToLive: AUTH_SESSION_DURATION,
onSuccess: () => {
update((state: AuthStore) => ({
...state,
identity: authClient?.getIdentity(),
}));

resolve();
},
onError: reject,
});
resolve();
},
onError: reject,
});
}),

signOut: async () => {
const authClient: AuthClient = await createAuthClient();
const client: AuthClient = authClient ?? (await createAuthClient());

await authClient.logout();
await client.logout();

update((state: AuthStore) => ({
...state,
Expand Down

0 comments on commit b699fd5

Please sign in to comment.