@logto/browser 0.1.3 → 0.1.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.
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { IdTokenClaims, OidcConfigResponse, Requester, UserInfoResponse } from '@logto/js';
1
+ import { IdTokenClaims, Requester, UserInfoResponse } from '@logto/js';
2
2
  import { Nullable } from '@silverhand/essentials';
3
3
  import { Infer } from 'superstruct';
4
4
  export type { IdTokenClaims, UserInfoResponse } from '@logto/js';
@@ -26,11 +26,20 @@ export declare const LogtoSignInSessionItemSchema: import("superstruct").Struct<
26
26
  }>;
27
27
  export declare type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;
28
28
  export default class LogtoClient {
29
- protected logtoConfig: LogtoConfig;
30
- protected oidcConfig?: OidcConfigResponse;
31
- protected logtoStorageKey: string;
32
- protected requester: Requester;
33
- protected accessTokenMap: Map<string, AccessToken>;
29
+ protected readonly logtoConfig: LogtoConfig;
30
+ protected readonly getOidcConfig: () => Promise<import("@silverhand/essentials").KeysToCamelCase<{
31
+ authorization_endpoint: string;
32
+ token_endpoint: string;
33
+ userinfo_endpoint: string;
34
+ end_session_endpoint: string;
35
+ revocation_endpoint: string;
36
+ jwks_uri: string;
37
+ issuer: string;
38
+ }>>;
39
+ protected readonly getJwtVerifyGetKey: () => Promise<import("jose/dist/types/types").GetKeyFunction<import("jose").JWSHeaderParameters, import("jose").FlattenedJWSInput>>;
40
+ protected readonly logtoStorageKey: string;
41
+ protected readonly requester: Requester;
42
+ protected readonly accessTokenMap: Map<string, AccessToken>;
34
43
  private readonly getAccessTokenPromiseMap;
35
44
  private _refreshToken;
36
45
  private _idToken;
@@ -50,7 +59,8 @@ export default class LogtoClient {
50
59
  handleSignInCallback(callbackUri: string): Promise<void>;
51
60
  signOut(postLogoutRedirectUri?: string): Promise<void>;
52
61
  private getAccessTokenByRefreshToken;
53
- private getOidcConfig;
62
+ private _getOidcConfig;
63
+ private _getJwtVerifyGetKey;
54
64
  private verifyIdToken;
55
65
  private saveCodeToken;
56
66
  }
package/lib/index.js CHANGED
@@ -9,10 +9,14 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
9
9
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
+ var __importDefault = (this && this.__importDefault) || function (mod) {
13
+ return (mod && mod.__esModule) ? mod : { "default": mod };
14
+ };
12
15
  Object.defineProperty(exports, "__esModule", { value: true });
13
16
  exports.LogtoSignInSessionItemSchema = void 0;
14
17
  const js_1 = require("@logto/js");
15
18
  const jose_1 = require("jose");
19
+ const lodash_once_1 = __importDefault(require("lodash.once"));
16
20
  const superstruct_1 = require("superstruct");
17
21
  const errors_1 = require("./errors");
18
22
  const utils_1 = require("./utils");
@@ -24,6 +28,8 @@ exports.LogtoSignInSessionItemSchema = (0, superstruct_1.type)({
24
28
  });
25
29
  class LogtoClient {
26
30
  constructor(logtoConfig, requester = (0, js_1.createRequester)()) {
31
+ this.getOidcConfig = (0, lodash_once_1.default)(this._getOidcConfig);
32
+ this.getJwtVerifyGetKey = (0, lodash_once_1.default)(this._getJwtVerifyGetKey);
27
33
  this.accessTokenMap = new Map();
28
34
  this.getAccessTokenPromiseMap = new Map();
29
35
  this.logtoConfig = logtoConfig;
@@ -90,8 +96,12 @@ class LogtoClient {
90
96
  if (accessToken && accessToken.expiresAt > Date.now() / 1000) {
91
97
  return accessToken.token;
92
98
  }
99
+ // Since the access token has expired, delete it from the map.
100
+ if (accessToken) {
101
+ this.accessTokenMap.delete(accessTokenKey);
102
+ }
93
103
  /**
94
- * Token has expired, need to fetch a new one using refresh token.
104
+ * Need to fetch a new access token using refresh token.
95
105
  * Reuse the cached promise if exists.
96
106
  */
97
107
  const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);
@@ -195,17 +205,12 @@ class LogtoClient {
195
205
  window.location.assign(url);
196
206
  }
197
207
  async getAccessTokenByRefreshToken(resource) {
198
- const accessTokenKey = (0, utils_1.buildAccessTokenKey)(resource);
199
- // Token expired, remove it from the map
200
- if (this.accessTokenMap.has(accessTokenKey)) {
201
- this.accessTokenMap.delete(accessTokenKey);
202
- }
203
- // Fetch new access token by refresh token
204
- const { clientId } = this.logtoConfig;
205
208
  if (!this.refreshToken) {
206
209
  throw new errors_1.LogtoClientError('not_authenticated');
207
210
  }
208
211
  try {
212
+ const accessTokenKey = (0, utils_1.buildAccessTokenKey)(resource);
213
+ const { clientId } = this.logtoConfig;
209
214
  const { tokenEndpoint } = await this.getOidcConfig();
210
215
  const { accessToken, refreshToken, idToken, scope, expiresIn } = await (0, js_1.fetchTokenByRefreshToken)({ clientId, tokenEndpoint, refreshToken: this.refreshToken, resource }, this.requester);
211
216
  this.accessTokenMap.set(accessTokenKey, {
@@ -224,19 +229,21 @@ class LogtoClient {
224
229
  throw new errors_1.LogtoClientError('get_access_token_by_refresh_token_failed', error);
225
230
  }
226
231
  }
227
- async getOidcConfig() {
228
- if (!this.oidcConfig) {
229
- const { endpoint } = this.logtoConfig;
230
- const discoveryEndpoint = (0, utils_1.getDiscoveryEndpoint)(endpoint);
231
- this.oidcConfig = await (0, js_1.fetchOidcConfig)(discoveryEndpoint, this.requester);
232
- }
233
- return this.oidcConfig;
232
+ async _getOidcConfig() {
233
+ const { endpoint } = this.logtoConfig;
234
+ const discoveryEndpoint = (0, utils_1.getDiscoveryEndpoint)(endpoint);
235
+ return (0, js_1.fetchOidcConfig)(discoveryEndpoint, this.requester);
236
+ }
237
+ async _getJwtVerifyGetKey() {
238
+ const { jwksUri } = await this.getOidcConfig();
239
+ return (0, jose_1.createRemoteJWKSet)(new URL(jwksUri));
234
240
  }
235
241
  async verifyIdToken(idToken) {
236
242
  const { clientId } = this.logtoConfig;
237
- const { issuer, jwksUri } = await this.getOidcConfig();
243
+ const { issuer } = await this.getOidcConfig();
244
+ const jwtVerifyGetKey = await this.getJwtVerifyGetKey();
238
245
  try {
239
- await (0, js_1.verifyIdToken)(idToken, clientId, issuer, (0, jose_1.createRemoteJWKSet)(new URL(jwksUri)));
246
+ await (0, js_1.verifyIdToken)(idToken, clientId, issuer, jwtVerifyGetKey);
240
247
  }
241
248
  catch (error) {
242
249
  throw new errors_1.LogtoClientError('invalid_id_token', error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logto/browser",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "main": "./lib/index.js",
5
5
  "exports": "./lib/index.js",
6
6
  "typings": "./lib/index.d.ts",
@@ -28,6 +28,7 @@
28
28
  "@silverhand/essentials": "^1.1.6",
29
29
  "jose": "^4.5.0",
30
30
  "lodash.get": "^4.4.2",
31
+ "lodash.once": "^4.1.1",
31
32
  "superstruct": "^0.15.3"
32
33
  },
33
34
  "devDependencies": {
@@ -36,6 +37,7 @@
36
37
  "@silverhand/ts-config": "^0.9.1",
37
38
  "@types/jest": "^27.4.0",
38
39
  "@types/lodash.get": "^4.4.6",
40
+ "@types/lodash.once": "^4.1.6",
39
41
  "eslint": "^8.9.0",
40
42
  "jest": "^27.5.1",
41
43
  "jest-location-mock": "^1.0.9",
@@ -53,5 +55,5 @@
53
55
  "publishConfig": {
54
56
  "access": "public"
55
57
  },
56
- "gitHead": "2a59d35046744dd1284eb81804cf0ef9a35f41e6"
58
+ "gitHead": "a5eed81a3e3db3184a53f04f843db8ac707dd3ad"
57
59
  }