react-native-nitro-auth 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,16 @@
1
1
  import type { Auth, AuthUser, AuthProvider, LoginOptions, AuthTokens } from "./Auth.nitro";
2
2
  import type { JSStorageAdapter } from "./js-storage-adapter";
3
3
  declare class AuthWeb implements Auth {
4
+ private readonly _config;
4
5
  private _currentUser;
5
6
  private _grantedScopes;
6
7
  private _listeners;
7
8
  private _tokenListeners;
8
9
  private _storageAdapter;
10
+ private _browserStorageResolved;
11
+ private _browserStorageCache;
12
+ private _refreshPromise;
13
+ private _appleSdkLoadPromise;
9
14
  constructor();
10
15
  private isPromiseLike;
11
16
  private createWebStorageDriver;
@@ -32,6 +37,7 @@ declare class AuthWeb implements Auth {
32
37
  revokeScopes(scopes: string[]): Promise<void>;
33
38
  getAccessToken(): Promise<string | undefined>;
34
39
  refreshToken(): Promise<AuthTokens>;
40
+ private performRefreshToken;
35
41
  private mapError;
36
42
  private parseResponseObject;
37
43
  private parseJwtPayload;
@@ -45,6 +51,7 @@ declare class AuthWeb implements Auth {
45
51
  private exchangeMicrosoftCodeForTokens;
46
52
  private getMicrosoftAuthBaseUrl;
47
53
  private decodeMicrosoftJwt;
54
+ private ensureAppleSdkLoaded;
48
55
  private loginApple;
49
56
  silentRestore(): Promise<void>;
50
57
  logout(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"Auth.web.d.ts","sourceRoot":"","sources":["../../../src/Auth.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgK7D,cAAM,OAAQ,YAAW,IAAI;IAC3B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,eAAe,CAA+B;;IAMtD,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,2BAA2B;IAgBnC,OAAO,CAAC,0BAA0B;IAYlC,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAIvB,IAAI,WAAW,IAAI,QAAQ,GAAG,SAAS,CAEtC;IAED,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,kBAAkB,CAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,GAC7C,MAAM,IAAI;IAQb,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAOrE,OAAO,CAAC,MAAM;IAMR,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAW7C,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IA8GzC,OAAO,CAAC,QAAQ;YAoBF,mBAAmB;IAQjC,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,oBAAoB;YA8Dd,WAAW;IAiFzB,OAAO,CAAC,eAAe;YAcT,cAAc;IA4G5B,OAAO,CAAC,oBAAoB;YAMd,qBAAqB;IAOnC,OAAO,CAAC,eAAe;YAKT,8BAA8B;IA+E5C,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;YAiBZ,UAAU;IAmDlB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAcpC,MAAM,IAAI,IAAI;IASd,OAAO,CAAC,UAAU;IAOlB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIzC,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI;IAQjE,IAAI,SAAU;IACd,OAAO;IACP,MAAM,CAAC,KAAK,EAAE,OAAO;CAGtB;AAED,eAAO,MAAM,UAAU,SAAgB,CAAC"}
1
+ {"version":3,"file":"Auth.web.d.ts","sourceRoot":"","sources":["../../../src/Auth.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgK7D,cAAM,OAAQ,YAAW,IAAI;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,oBAAoB,CAA4B;;IAOxD,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IAsCzB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,2BAA2B;IAgBnC,OAAO,CAAC,0BAA0B;IAYlC,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAIvB,IAAI,WAAW,IAAI,QAAQ,GAAG,SAAS,CAEtC;IAED,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,kBAAkB,CAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,GAC7C,MAAM,IAAI;IAQb,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAOrE,OAAO,CAAC,MAAM;IAMR,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAW7C,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;YAgB3B,mBAAmB;IA6GjC,OAAO,CAAC,QAAQ;YAoBF,mBAAmB;IAQjC,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,oBAAoB;YA8Dd,WAAW;IAgFzB,OAAO,CAAC,eAAe;YAcT,cAAc;IA2G5B,OAAO,CAAC,oBAAoB;YAMd,qBAAqB;IAOnC,OAAO,CAAC,eAAe;YAKT,8BAA8B;IA8E5C,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;YAiBZ,oBAAoB;YA2DpB,UAAU;IAqClB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAcpC,MAAM,IAAI,IAAI;IASd,OAAO,CAAC,UAAU;IAOlB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIzC,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI;IAQjE,IAAI,SAAU;IACd,OAAO;IACP,MAAM,CAAC,KAAK,EAAE,OAAO;CAGtB;AAED,eAAO,MAAM,UAAU,SAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-auth.d.ts","sourceRoot":"","sources":["../../../src/use-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AAGtB,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AAYF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG;IACtC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,OAAO,IAAI,aAAa,CAuKvC"}
1
+ {"version":3,"file":"use-auth.d.ts","sourceRoot":"","sources":["../../../src/use-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AAGtB,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AA0BF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG;IACtC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,OAAO,IAAI,aAAa,CAyLvC"}
@@ -1,11 +1,16 @@
1
1
  import type { Auth, AuthUser, AuthProvider, LoginOptions, AuthTokens } from "./Auth.nitro";
2
2
  import type { JSStorageAdapter } from "./js-storage-adapter";
3
3
  declare class AuthWeb implements Auth {
4
+ private readonly _config;
4
5
  private _currentUser;
5
6
  private _grantedScopes;
6
7
  private _listeners;
7
8
  private _tokenListeners;
8
9
  private _storageAdapter;
10
+ private _browserStorageResolved;
11
+ private _browserStorageCache;
12
+ private _refreshPromise;
13
+ private _appleSdkLoadPromise;
9
14
  constructor();
10
15
  private isPromiseLike;
11
16
  private createWebStorageDriver;
@@ -32,6 +37,7 @@ declare class AuthWeb implements Auth {
32
37
  revokeScopes(scopes: string[]): Promise<void>;
33
38
  getAccessToken(): Promise<string | undefined>;
34
39
  refreshToken(): Promise<AuthTokens>;
40
+ private performRefreshToken;
35
41
  private mapError;
36
42
  private parseResponseObject;
37
43
  private parseJwtPayload;
@@ -45,6 +51,7 @@ declare class AuthWeb implements Auth {
45
51
  private exchangeMicrosoftCodeForTokens;
46
52
  private getMicrosoftAuthBaseUrl;
47
53
  private decodeMicrosoftJwt;
54
+ private ensureAppleSdkLoaded;
48
55
  private loginApple;
49
56
  silentRestore(): Promise<void>;
50
57
  logout(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"Auth.web.d.ts","sourceRoot":"","sources":["../../../src/Auth.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgK7D,cAAM,OAAQ,YAAW,IAAI;IAC3B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,eAAe,CAA+B;;IAMtD,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,2BAA2B;IAgBnC,OAAO,CAAC,0BAA0B;IAYlC,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAIvB,IAAI,WAAW,IAAI,QAAQ,GAAG,SAAS,CAEtC;IAED,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,kBAAkB,CAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,GAC7C,MAAM,IAAI;IAQb,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAOrE,OAAO,CAAC,MAAM;IAMR,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAW7C,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IA8GzC,OAAO,CAAC,QAAQ;YAoBF,mBAAmB;IAQjC,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,oBAAoB;YA8Dd,WAAW;IAiFzB,OAAO,CAAC,eAAe;YAcT,cAAc;IA4G5B,OAAO,CAAC,oBAAoB;YAMd,qBAAqB;IAOnC,OAAO,CAAC,eAAe;YAKT,8BAA8B;IA+E5C,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;YAiBZ,UAAU;IAmDlB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAcpC,MAAM,IAAI,IAAI;IASd,OAAO,CAAC,UAAU;IAOlB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIzC,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI;IAQjE,IAAI,SAAU;IACd,OAAO;IACP,MAAM,CAAC,KAAK,EAAE,OAAO;CAGtB;AAED,eAAO,MAAM,UAAU,SAAgB,CAAC"}
1
+ {"version":3,"file":"Auth.web.d.ts","sourceRoot":"","sources":["../../../src/Auth.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgK7D,cAAM,OAAQ,YAAW,IAAI;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,oBAAoB,CAA4B;;IAOxD,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IAsCzB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,2BAA2B;IAgBnC,OAAO,CAAC,0BAA0B;IAYlC,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAIvB,IAAI,WAAW,IAAI,QAAQ,GAAG,SAAS,CAEtC;IAED,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,kBAAkB,CAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,KAAK,IAAI,GAC7C,MAAM,IAAI;IAQb,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAOrE,OAAO,CAAC,MAAM;IAMR,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAW7C,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;YAgB3B,mBAAmB;IA6GjC,OAAO,CAAC,QAAQ;YAoBF,mBAAmB;IAQjC,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,oBAAoB;YA8Dd,WAAW;IAgFzB,OAAO,CAAC,eAAe;YAcT,cAAc;IA2G5B,OAAO,CAAC,oBAAoB;YAMd,qBAAqB;IAOnC,OAAO,CAAC,eAAe;YAKT,8BAA8B;IA8E5C,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;YAiBZ,oBAAoB;YA2DpB,UAAU;IAqClB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAcpC,MAAM,IAAI,IAAI;IASd,OAAO,CAAC,UAAU;IAOlB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIzC,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI;IAQjE,IAAI,SAAU;IACd,OAAO;IACP,MAAM,CAAC,KAAK,EAAE,OAAO;CAGtB;AAED,eAAO,MAAM,UAAU,SAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-auth.d.ts","sourceRoot":"","sources":["../../../src/use-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AAGtB,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AAYF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG;IACtC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,OAAO,IAAI,aAAa,CAuKvC"}
1
+ {"version":3,"file":"use-auth.d.ts","sourceRoot":"","sources":["../../../src/use-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACX,MAAM,cAAc,CAAC;AAGtB,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AA0BF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG;IACtC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,OAAO,IAAI,aAAa,CAyLvC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-auth",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "High-performance authentication library for React Native with Google Sign-In, Apple Sign-In, and Microsoft Sign-In support, powered by Nitro Modules (JSI)",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -35,7 +35,7 @@ Pod::Spec.new do |s|
35
35
  s.frameworks = ["Security"]
36
36
 
37
37
  s.dependency "React-Core"
38
- s.dependency "GoogleSignIn", "~> 9.0"
38
+ s.dependency "GoogleSignIn", "~> 9.1"
39
39
 
40
40
  load 'nitrogen/generated/ios/NitroAuth+autolinking.rb'
41
41
  add_nitrogen_files(s)
package/src/Auth.web.ts CHANGED
@@ -166,13 +166,19 @@ const getConfig = (): AuthWebExtraConfig => {
166
166
  };
167
167
 
168
168
  class AuthWeb implements Auth {
169
+ private readonly _config: AuthWebExtraConfig;
169
170
  private _currentUser: AuthUser | undefined;
170
171
  private _grantedScopes: string[] = [];
171
172
  private _listeners: ((user: AuthUser | undefined) => void)[] = [];
172
173
  private _tokenListeners: ((tokens: AuthTokens) => void)[] = [];
173
174
  private _storageAdapter: WebStorageDriver | undefined;
175
+ private _browserStorageResolved = false;
176
+ private _browserStorageCache: Storage | undefined;
177
+ private _refreshPromise: Promise<AuthTokens> | undefined;
178
+ private _appleSdkLoadPromise: Promise<void> | undefined;
174
179
 
175
180
  constructor() {
181
+ this._config = getConfig();
176
182
  this.loadFromCache();
177
183
  }
178
184
 
@@ -213,11 +219,11 @@ class AuthWeb implements Auth {
213
219
  if (this._storageAdapter) {
214
220
  return true;
215
221
  }
216
- return getConfig().nitroAuthPersistTokensOnWeb === true;
222
+ return this._config.nitroAuthPersistTokensOnWeb === true;
217
223
  }
218
224
 
219
225
  private getWebStorageMode(): "session" | "local" | "memory" {
220
- const configuredMode = getConfig().nitroAuthWebStorage;
226
+ const configuredMode = this._config.nitroAuthWebStorage;
221
227
  if (configuredMode && WEB_STORAGE_MODES.has(configuredMode)) {
222
228
  return configuredMode;
223
229
  }
@@ -225,12 +231,19 @@ class AuthWeb implements Auth {
225
231
  }
226
232
 
227
233
  private getBrowserStorage(): Storage | undefined {
234
+ if (this._browserStorageResolved) {
235
+ return this._browserStorageCache;
236
+ }
237
+
238
+ this._browserStorageResolved = true;
228
239
  if (typeof window === "undefined") {
240
+ this._browserStorageCache = undefined;
229
241
  return undefined;
230
242
  }
231
243
 
232
244
  const mode = this.getWebStorageMode();
233
245
  if (mode === STORAGE_MODE_MEMORY) {
246
+ this._browserStorageCache = undefined;
234
247
  return undefined;
235
248
  }
236
249
 
@@ -240,6 +253,7 @@ class AuthWeb implements Auth {
240
253
  const testKey = "__nitro_auth_storage_probe__";
241
254
  storage.setItem(testKey, "1");
242
255
  storage.removeItem(testKey);
256
+ this._browserStorageCache = storage;
243
257
  return storage;
244
258
  } catch (error) {
245
259
  logger.warn(
@@ -249,6 +263,7 @@ class AuthWeb implements Auth {
249
263
  error: String(error),
250
264
  },
251
265
  );
266
+ this._browserStorageCache = undefined;
252
267
  return undefined;
253
268
  }
254
269
  }
@@ -499,6 +514,22 @@ class AuthWeb implements Auth {
499
514
  }
500
515
 
501
516
  async refreshToken(): Promise<AuthTokens> {
517
+ if (this._refreshPromise) {
518
+ return this._refreshPromise;
519
+ }
520
+
521
+ const refreshPromise = this.performRefreshToken();
522
+ this._refreshPromise = refreshPromise;
523
+ try {
524
+ return await refreshPromise;
525
+ } finally {
526
+ if (this._refreshPromise === refreshPromise) {
527
+ this._refreshPromise = undefined;
528
+ }
529
+ }
530
+ }
531
+
532
+ private async performRefreshToken(): Promise<AuthTokens> {
502
533
  if (!this._currentUser) {
503
534
  throw new Error("No user logged in");
504
535
  }
@@ -511,15 +542,14 @@ class AuthWeb implements Auth {
511
542
  throw new Error("No refresh token available");
512
543
  }
513
544
 
514
- const config = getConfig();
515
- const clientId = config.microsoftClientId;
545
+ const clientId = this._config.microsoftClientId;
516
546
  if (!clientId) {
517
547
  throw new Error(
518
548
  "Microsoft Client ID not configured. Add 'microsoftClientId' to expo.extra in your app.config.js",
519
549
  );
520
550
  }
521
- const tenant = config.microsoftTenant ?? "common";
522
- const b2cDomain = config.microsoftB2cDomain;
551
+ const tenant = this._config.microsoftTenant ?? "common";
552
+ const b2cDomain = this._config.microsoftB2cDomain;
523
553
 
524
554
  const authBaseUrl = this.getMicrosoftAuthBaseUrl(tenant, b2cDomain);
525
555
  const tokenUrl = `${authBaseUrl}oauth2/v2.0/token`;
@@ -642,7 +672,9 @@ class AuthWeb implements Auth {
642
672
  throw new Error("Invalid JWT payload");
643
673
  }
644
674
 
645
- const decoded: unknown = JSON.parse(atob(payload));
675
+ const normalizedPayload = payload.replace(/-/g, "+").replace(/_/g, "/");
676
+ const padding = "=".repeat((4 - (normalizedPayload.length % 4)) % 4);
677
+ const decoded: unknown = JSON.parse(atob(`${normalizedPayload}${padding}`));
646
678
  if (!isJsonObject(decoded)) {
647
679
  throw new Error("Expected JWT payload to be an object");
648
680
  }
@@ -715,8 +747,7 @@ class AuthWeb implements Auth {
715
747
  scopes: string[],
716
748
  loginHint?: string,
717
749
  ): Promise<void> {
718
- const config = getConfig();
719
- const clientId = config.googleWebClientId;
750
+ const clientId = this._config.googleWebClientId;
720
751
 
721
752
  if (!clientId) {
722
753
  throw new Error(
@@ -812,8 +843,7 @@ class AuthWeb implements Auth {
812
843
  tenant?: string,
813
844
  prompt?: string,
814
845
  ): Promise<void> {
815
- const config = getConfig();
816
- const clientId = config.microsoftClientId;
846
+ const clientId = this._config.microsoftClientId;
817
847
 
818
848
  if (!clientId) {
819
849
  throw new Error(
@@ -821,8 +851,8 @@ class AuthWeb implements Auth {
821
851
  );
822
852
  }
823
853
 
824
- const effectiveTenant = tenant ?? config.microsoftTenant ?? "common";
825
- const b2cDomain = config.microsoftB2cDomain;
854
+ const effectiveTenant = tenant ?? this._config.microsoftTenant ?? "common";
855
+ const b2cDomain = this._config.microsoftB2cDomain;
826
856
  const authBaseUrl = this.getMicrosoftAuthBaseUrl(
827
857
  effectiveTenant,
828
858
  b2cDomain,
@@ -941,10 +971,9 @@ class AuthWeb implements Auth {
941
971
  expectedNonce: string,
942
972
  scopes: string[],
943
973
  ): Promise<void> {
944
- const config = getConfig();
945
974
  const authBaseUrl = this.getMicrosoftAuthBaseUrl(
946
975
  tenant,
947
- config.microsoftB2cDomain,
976
+ this._config.microsoftB2cDomain,
948
977
  );
949
978
  const tokenUrl = `${authBaseUrl}oauth2/v2.0/token`;
950
979
 
@@ -1040,55 +1069,100 @@ class AuthWeb implements Auth {
1040
1069
  }
1041
1070
  }
1042
1071
 
1043
- private async loginApple(): Promise<void> {
1044
- const config = getConfig();
1045
- const clientId = config.appleWebClientId;
1072
+ private async ensureAppleSdkLoaded(): Promise<void> {
1073
+ if (window.AppleID) {
1074
+ return;
1075
+ }
1046
1076
 
1047
- if (!clientId) {
1048
- throw new Error(
1049
- "Apple Web Client ID not configured. Add 'APPLE_WEB_CLIENT_ID' to your .env file.",
1050
- );
1077
+ if (this._appleSdkLoadPromise) {
1078
+ return this._appleSdkLoadPromise;
1051
1079
  }
1052
1080
 
1053
- return new Promise((resolve, reject) => {
1081
+ this._appleSdkLoadPromise = new Promise<void>((resolve, reject) => {
1082
+ const scriptId = "nitro-auth-apple-sdk";
1083
+ const existingScript = document.getElementById(
1084
+ scriptId,
1085
+ ) as HTMLScriptElement | null;
1086
+
1087
+ if (existingScript) {
1088
+ if (window.AppleID) {
1089
+ resolve();
1090
+ return;
1091
+ }
1092
+
1093
+ existingScript.addEventListener(
1094
+ "load",
1095
+ () => {
1096
+ resolve();
1097
+ },
1098
+ {
1099
+ once: true,
1100
+ },
1101
+ );
1102
+ existingScript.addEventListener(
1103
+ "error",
1104
+ () => {
1105
+ this._appleSdkLoadPromise = undefined;
1106
+ reject(new Error("Failed to load Apple SDK"));
1107
+ },
1108
+ { once: true },
1109
+ );
1110
+ return;
1111
+ }
1112
+
1054
1113
  const script = document.createElement("script");
1114
+ script.id = scriptId;
1055
1115
  script.src =
1056
1116
  "https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js";
1057
1117
  script.async = true;
1058
1118
  script.onload = () => {
1059
- if (!window.AppleID) {
1060
- reject(new Error("Apple SDK not loaded"));
1061
- return;
1062
- }
1063
- window.AppleID.auth.init({
1064
- clientId,
1065
- scope: "name email",
1066
- redirectURI: window.location.origin,
1067
- usePopup: true,
1068
- });
1069
- window.AppleID.auth
1070
- .signIn()
1071
- .then((response: AppleAuthResponse) => {
1072
- const user: AuthUser = {
1073
- provider: "apple",
1074
- idToken: response.authorization.id_token,
1075
- email: response.user?.email,
1076
- name: response.user?.name
1077
- ? `${response.user.name.firstName} ${response.user.name.lastName}`.trim()
1078
- : undefined,
1079
- };
1080
- this.updateUser(user);
1081
- resolve();
1082
- })
1083
- .catch((err: unknown) => {
1084
- reject(this.mapError(err));
1085
- });
1119
+ resolve();
1086
1120
  };
1087
1121
  script.onerror = () => {
1122
+ this._appleSdkLoadPromise = undefined;
1088
1123
  reject(new Error("Failed to load Apple SDK"));
1089
1124
  };
1090
1125
  document.head.appendChild(script);
1091
1126
  });
1127
+
1128
+ return this._appleSdkLoadPromise;
1129
+ }
1130
+
1131
+ private async loginApple(): Promise<void> {
1132
+ const clientId = this._config.appleWebClientId;
1133
+
1134
+ if (!clientId) {
1135
+ throw new Error(
1136
+ "Apple Web Client ID not configured. Add 'APPLE_WEB_CLIENT_ID' to your .env file.",
1137
+ );
1138
+ }
1139
+
1140
+ await this.ensureAppleSdkLoaded();
1141
+ if (!window.AppleID) {
1142
+ throw new Error("Apple SDK not loaded");
1143
+ }
1144
+
1145
+ window.AppleID.auth.init({
1146
+ clientId,
1147
+ scope: "name email",
1148
+ redirectURI: window.location.origin,
1149
+ usePopup: true,
1150
+ });
1151
+
1152
+ try {
1153
+ const response: AppleAuthResponse = await window.AppleID.auth.signIn();
1154
+ const user: AuthUser = {
1155
+ provider: "apple",
1156
+ idToken: response.authorization.id_token,
1157
+ email: response.user?.email,
1158
+ name: response.user?.name
1159
+ ? `${response.user.name.firstName} ${response.user.name.lastName}`.trim()
1160
+ : undefined,
1161
+ };
1162
+ this.updateUser(user);
1163
+ } catch (error) {
1164
+ throw this.mapError(error);
1165
+ }
1092
1166
  }
1093
1167
 
1094
1168
  async silentRestore(): Promise<void> {
package/src/service.ts CHANGED
@@ -54,8 +54,8 @@ export const AuthService: Auth = {
54
54
  },
55
55
 
56
56
  onAuthStateChanged(callback: (user: AuthUser | undefined) => void) {
57
- return nitroAuth.onAuthStateChanged(() => {
58
- callback(AuthService.currentUser);
57
+ return nitroAuth.onAuthStateChanged((user) => {
58
+ callback(user);
59
59
  });
60
60
  },
61
61
 
package/src/use-auth.ts CHANGED
@@ -14,6 +14,20 @@ type AuthState = {
14
14
  error: Error | undefined;
15
15
  };
16
16
 
17
+ const areScopesEqual = (left: string[], right: string[]): boolean => {
18
+ if (left.length !== right.length) {
19
+ return false;
20
+ }
21
+
22
+ for (let index = 0; index < left.length; index += 1) {
23
+ if (left[index] !== right[index]) {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ return true;
29
+ };
30
+
17
31
  class AuthHookError extends Error {
18
32
  public readonly underlyingError?: string;
19
33
 
@@ -43,17 +57,37 @@ export function useAuth(): UseAuthReturn {
43
57
  error: undefined,
44
58
  });
45
59
 
60
+ const syncStateFromService = useCallback(
61
+ (nextLoading: boolean, nextError: Error | undefined) => {
62
+ const nextUser = AuthService.currentUser;
63
+ const nextScopes = AuthService.grantedScopes;
64
+ setState((prev) => {
65
+ if (
66
+ prev.loading === nextLoading &&
67
+ prev.error === nextError &&
68
+ prev.user === nextUser &&
69
+ areScopesEqual(prev.scopes, nextScopes)
70
+ ) {
71
+ return prev;
72
+ }
73
+
74
+ return {
75
+ user: nextUser,
76
+ scopes: nextScopes,
77
+ loading: nextLoading,
78
+ error: nextError,
79
+ };
80
+ });
81
+ },
82
+ [],
83
+ );
84
+
46
85
  const login = useCallback(
47
86
  async (provider: AuthProvider, options?: LoginOptions) => {
48
87
  setState((prev) => ({ ...prev, loading: true, error: undefined }));
49
88
  try {
50
89
  await AuthService.login(provider, options);
51
- setState({
52
- user: AuthService.currentUser,
53
- scopes: AuthService.grantedScopes,
54
- loading: false,
55
- error: undefined,
56
- });
90
+ syncStateFromService(false, undefined);
57
91
  } catch (e) {
58
92
  const error = e instanceof Error ? e : new Error(String(e));
59
93
  setState((prev) => ({
@@ -64,7 +98,7 @@ export function useAuth(): UseAuthReturn {
64
98
  throw error;
65
99
  }
66
100
  },
67
- [],
101
+ [syncStateFromService],
68
102
  );
69
103
 
70
104
  const logout = useCallback(() => {
@@ -77,47 +111,43 @@ export function useAuth(): UseAuthReturn {
77
111
  });
78
112
  }, []);
79
113
 
80
- const requestScopes = useCallback(async (newScopes: string[]) => {
81
- setState((prev) => ({ ...prev, loading: true, error: undefined }));
82
- try {
83
- await AuthService.requestScopes(newScopes);
84
- setState({
85
- user: AuthService.currentUser,
86
- scopes: AuthService.grantedScopes,
87
- loading: false,
88
- error: undefined,
89
- });
90
- } catch (e) {
91
- const error = e instanceof Error ? e : new Error(String(e));
92
- setState((prev) => ({
93
- ...prev,
94
- loading: false,
95
- error,
96
- }));
97
- throw error;
98
- }
99
- }, []);
114
+ const requestScopes = useCallback(
115
+ async (newScopes: string[]) => {
116
+ setState((prev) => ({ ...prev, loading: true, error: undefined }));
117
+ try {
118
+ await AuthService.requestScopes(newScopes);
119
+ syncStateFromService(false, undefined);
120
+ } catch (e) {
121
+ const error = e instanceof Error ? e : new Error(String(e));
122
+ setState((prev) => ({
123
+ ...prev,
124
+ loading: false,
125
+ error,
126
+ }));
127
+ throw error;
128
+ }
129
+ },
130
+ [syncStateFromService],
131
+ );
100
132
 
101
- const revokeScopes = useCallback(async (scopesToRevoke: string[]) => {
102
- setState((prev) => ({ ...prev, loading: true, error: undefined }));
103
- try {
104
- await AuthService.revokeScopes(scopesToRevoke);
105
- setState({
106
- user: AuthService.currentUser,
107
- scopes: AuthService.grantedScopes,
108
- loading: false,
109
- error: undefined,
110
- });
111
- } catch (e) {
112
- const error = e instanceof Error ? e : new Error(String(e));
113
- setState((prev) => ({
114
- ...prev,
115
- loading: false,
116
- error,
117
- }));
118
- throw error;
119
- }
120
- }, []);
133
+ const revokeScopes = useCallback(
134
+ async (scopesToRevoke: string[]) => {
135
+ setState((prev) => ({ ...prev, loading: true, error: undefined }));
136
+ try {
137
+ await AuthService.revokeScopes(scopesToRevoke);
138
+ syncStateFromService(false, undefined);
139
+ } catch (e) {
140
+ const error = e instanceof Error ? e : new Error(String(e));
141
+ setState((prev) => ({
142
+ ...prev,
143
+ loading: false,
144
+ error,
145
+ }));
146
+ throw error;
147
+ }
148
+ },
149
+ [syncStateFromService],
150
+ );
121
151
 
122
152
  const getAccessToken = useCallback(() => AuthService.getAccessToken(), []);
123
153
 
@@ -125,12 +155,7 @@ export function useAuth(): UseAuthReturn {
125
155
  setState((prev) => ({ ...prev, loading: true, error: undefined }));
126
156
  try {
127
157
  const tokens = await AuthService.refreshToken();
128
- setState({
129
- user: AuthService.currentUser,
130
- scopes: AuthService.grantedScopes,
131
- loading: false,
132
- error: undefined,
133
- });
158
+ syncStateFromService(false, undefined);
134
159
  return tokens;
135
160
  } catch (e) {
136
161
  const msg = e instanceof Error ? e.message : String(e);
@@ -145,18 +170,13 @@ export function useAuth(): UseAuthReturn {
145
170
  }));
146
171
  throw authError;
147
172
  }
148
- }, []);
173
+ }, [syncStateFromService]);
149
174
 
150
175
  const silentRestore = useCallback(async () => {
151
176
  setState((prev) => ({ ...prev, loading: true, error: undefined }));
152
177
  try {
153
178
  await AuthService.silentRestore();
154
- setState({
155
- user: AuthService.currentUser,
156
- scopes: AuthService.grantedScopes,
157
- loading: false,
158
- error: undefined,
159
- });
179
+ syncStateFromService(false, undefined);
160
180
  } catch (e) {
161
181
  const error = e instanceof Error ? e : new Error(String(e));
162
182
  setState((prev) => ({
@@ -166,15 +186,27 @@ export function useAuth(): UseAuthReturn {
166
186
  }));
167
187
  throw error;
168
188
  }
169
- }, []);
189
+ }, [syncStateFromService]);
170
190
 
171
191
  useEffect(() => {
172
192
  const unsubscribe = AuthService.onAuthStateChanged((currentUser) => {
173
- setState((prev) => ({
174
- ...prev,
175
- user: currentUser,
176
- scopes: AuthService.grantedScopes,
177
- }));
193
+ const nextScopes = AuthService.grantedScopes;
194
+ setState((prev) => {
195
+ if (
196
+ prev.user === currentUser &&
197
+ areScopesEqual(prev.scopes, nextScopes) &&
198
+ prev.loading === false
199
+ ) {
200
+ return prev;
201
+ }
202
+
203
+ return {
204
+ ...prev,
205
+ user: currentUser,
206
+ scopes: nextScopes,
207
+ loading: false,
208
+ };
209
+ });
178
210
  });
179
211
  return unsubscribe;
180
212
  }, []);