@logto/client 1.1.1 → 2.0.0

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.js CHANGED
@@ -1,285 +1,194 @@
1
- var $4R6L3$logtojs = require("@logto/js");
2
- var $4R6L3$jose = require("jose");
3
- var $4R6L3$lodashonce = require("lodash.once");
4
- var $4R6L3$lodashget = require("lodash.get");
5
-
6
- function $parcel$interopDefault(a) {
7
- return a && a.__esModule ? a.default : a;
8
- }
9
- function $parcel$defineInteropFlag(a) {
10
- Object.defineProperty(a, '__esModule', {value: true, configurable: true});
11
- }
12
- function $parcel$exportWildcard(dest, source) {
13
- Object.keys(source).forEach(function(key) {
14
- if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
15
- return;
16
- }
17
-
18
- Object.defineProperty(dest, key, {
19
- enumerable: true,
20
- get: function get() {
21
- return source[key];
22
- }
23
- });
24
- });
25
-
26
- return dest;
27
- }
28
- function $parcel$export(e, n, v, s) {
29
- Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
30
- }
31
-
32
- $parcel$defineInteropFlag(module.exports);
33
-
34
- $parcel$export(module.exports, "default", () => $f73788ae50447ce9$export$2e2bcd8739ae039);
35
- $parcel$export(module.exports, "LogtoError", () => $f73788ae50447ce9$re_export$LogtoError);
36
- $parcel$export(module.exports, "OidcError", () => $f73788ae50447ce9$re_export$OidcError);
37
- $parcel$export(module.exports, "Prompt", () => $4R6L3$logtojs.Prompt);
38
- $parcel$export(module.exports, "LogtoRequestError", () => $f73788ae50447ce9$re_export$LogtoRequestError);
39
- $parcel$export(module.exports, "ReservedScope", () => $f73788ae50447ce9$re_export$ReservedScope);
40
- $parcel$export(module.exports, "UserScope", () => $f73788ae50447ce9$re_export$UserScope);
41
- $parcel$export(module.exports, "createRequester", () => $b455f57f80fbf6bf$export$8d54726fdbf08e0a);
42
-
43
-
44
-
45
- var $9166104b36889c59$exports = {};
46
-
47
- $parcel$export($9166104b36889c59$exports, "LogtoClientError", () => $9166104b36889c59$export$877962ca249b8fc8);
48
-
49
- const $9166104b36889c59$var$logtoClientErrorCodes = Object.freeze({
50
- sign_in_session: {
51
- invalid: "Invalid sign-in session.",
52
- not_found: "Sign-in session not found."
53
- },
54
- not_authenticated: "Not authenticated.",
55
- fetch_user_info_failed: "Unable to fetch user info. The access token may be invalid."
56
- });
57
- const $9166104b36889c59$var$getMessageByErrorCode = (errorCode)=>{
58
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
59
- const message = (0, ($parcel$interopDefault($4R6L3$lodashget)))($9166104b36889c59$var$logtoClientErrorCodes, errorCode);
60
- if (typeof message === "string") return message;
61
- return errorCode;
62
- };
63
- class $9166104b36889c59$export$877962ca249b8fc8 extends Error {
64
- constructor(code, data){
65
- super($9166104b36889c59$var$getMessageByErrorCode(code));
66
- this.code = code;
67
- this.data = data;
68
- }
69
- }
70
-
71
-
72
- var $6d3989f7f53311af$exports = {};
73
-
74
- $parcel$export($6d3989f7f53311af$exports, "isLogtoSignInSessionItem", () => $6d3989f7f53311af$export$5d8adf6e063019de);
75
- $parcel$export($6d3989f7f53311af$exports, "isLogtoAccessTokenMap", () => $6d3989f7f53311af$export$c12fab42a9a3e2a6);
76
-
77
- const $6d3989f7f53311af$export$5d8adf6e063019de = (data)=>{
78
- if (!(0, $4R6L3$logtojs.isArbitraryObject)(data)) return false;
79
- return [
80
- "redirectUri",
81
- "codeVerifier",
82
- "state"
83
- ].every((key)=>typeof data[key] === "string");
84
- };
85
- const $6d3989f7f53311af$export$c12fab42a9a3e2a6 = (data)=>{
86
- if (!(0, $4R6L3$logtojs.isArbitraryObject)(data)) return false;
87
- return Object.values(data).every((value)=>{
88
- if (!(0, $4R6L3$logtojs.isArbitraryObject)(value)) return false;
89
- return typeof value.token === "string" && typeof value.scope === "string" && typeof value.expiresAt === "number";
90
- });
91
- };
92
-
93
-
94
-
95
-
96
- const $b455f57f80fbf6bf$export$8d54726fdbf08e0a = (fetchFunction)=>{
97
- return async (...args)=>{
98
- const response = await fetchFunction(...args);
99
- if (!response.ok) {
100
- const responseJson = await response.json();
101
- if (!(0, $4R6L3$logtojs.isLogtoRequestError)(responseJson)) throw new (0, $4R6L3$logtojs.LogtoError)("unexpected_response_error", responseJson);
102
- // Expected request error from server
103
- const { code: code , message: message } = responseJson;
104
- throw new (0, $4R6L3$logtojs.LogtoRequestError)(code, message);
105
- }
106
- return response.json();
107
- };
108
- };
109
-
110
-
111
- const $e2aabdbdb3cc09f0$export$8f595bd2a47bcea6 = (resource = "", scopes = [])=>`${scopes.slice().sort().join(" ")}@${resource}`;
112
- const $e2aabdbdb3cc09f0$export$5d9c34f69c80822b = (endpoint)=>new URL((0, $4R6L3$logtojs.discoveryPath), endpoint).toString();
113
-
114
-
115
-
116
-
117
-
118
-
119
- class $f73788ae50447ce9$export$2e2bcd8739ae039 {
120
- getOidcConfig = (0, ($parcel$interopDefault($4R6L3$lodashonce)))(this._getOidcConfig);
121
- getJwtVerifyGetKey = (0, ($parcel$interopDefault($4R6L3$lodashonce)))(this._getJwtVerifyGetKey);
122
- accessTokenMap = new Map();
123
- constructor(logtoConfig, adapter){
1
+ import { Prompt, withDefaultScopes, decodeIdToken, fetchUserInfo, generateSignInUri, verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode, revoke, generateSignOutUri, fetchTokenByRefreshToken, fetchOidcConfig, verifyIdToken } from '@logto/js';
2
+ export { LogtoError, LogtoRequestError, OidcError, Prompt, ReservedScope, UserScope } from '@logto/js';
3
+ import { createRemoteJWKSet } from 'jose';
4
+ import { LogtoClientError } from './errors.js';
5
+ import { isLogtoSignInSessionItem, isLogtoAccessTokenMap } from './types/index.js';
6
+ import { buildAccessTokenKey, getDiscoveryEndpoint } from './utils/index.js';
7
+ import { once } from './utils/once.js';
8
+ export { createRequester } from './utils/requester.js';
9
+
10
+ class LogtoClient {
11
+ constructor(logtoConfig, adapter) {
12
+ this.getOidcConfig = once(this._getOidcConfig);
13
+ this.getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);
14
+ this.accessTokenMap = new Map();
124
15
  this.logtoConfig = {
125
16
  ...logtoConfig,
126
- prompt: logtoConfig.prompt ?? (0, $4R6L3$logtojs.Prompt).Consent,
127
- scopes: (0, $4R6L3$logtojs.withDefaultScopes)(logtoConfig.scopes).split(" ")
17
+ prompt: logtoConfig.prompt ?? Prompt.Consent,
18
+ scopes: withDefaultScopes(logtoConfig.scopes).split(' '),
128
19
  };
129
20
  this.adapter = adapter;
130
- this.loadAccessTokenMap();
21
+ void this.loadAccessTokenMap();
131
22
  }
132
23
  async isAuthenticated() {
133
24
  return Boolean(await this.getIdToken());
134
25
  }
135
26
  async getRefreshToken() {
136
- return this.adapter.storage.getItem("refreshToken");
27
+ return this.adapter.storage.getItem('refreshToken');
137
28
  }
138
29
  async getIdToken() {
139
- return this.adapter.storage.getItem("idToken");
30
+ return this.adapter.storage.getItem('idToken');
140
31
  }
141
32
  async getAccessToken(resource) {
142
- if (!await this.getIdToken()) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("not_authenticated");
143
- const accessTokenKey = (0, $e2aabdbdb3cc09f0$export$8f595bd2a47bcea6)(resource);
33
+ if (!(await this.getIdToken())) {
34
+ throw new LogtoClientError('not_authenticated');
35
+ }
36
+ const accessTokenKey = buildAccessTokenKey(resource);
144
37
  const accessToken = this.accessTokenMap.get(accessTokenKey);
145
- if (accessToken && accessToken.expiresAt > Date.now() / 1000) return accessToken.token;
38
+ if (accessToken && accessToken.expiresAt > Date.now() / 1000) {
39
+ return accessToken.token;
40
+ }
146
41
  // Since the access token has expired, delete it from the map.
147
- if (accessToken) this.accessTokenMap.delete(accessTokenKey);
42
+ if (accessToken) {
43
+ this.accessTokenMap.delete(accessTokenKey);
44
+ }
148
45
  /**
149
- * Need to fetch a new access token using refresh token.
150
- */ return this.getAccessTokenByRefreshToken(resource);
46
+ * Need to fetch a new access token using refresh token.
47
+ */
48
+ return this.getAccessTokenByRefreshToken(resource);
151
49
  }
152
50
  async getIdTokenClaims() {
153
51
  const idToken = await this.getIdToken();
154
- if (!idToken) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("not_authenticated");
155
- return (0, $4R6L3$logtojs.decodeIdToken)(idToken);
52
+ if (!idToken) {
53
+ throw new LogtoClientError('not_authenticated');
54
+ }
55
+ return decodeIdToken(idToken);
156
56
  }
157
57
  async fetchUserInfo() {
158
- const { userinfoEndpoint: userinfoEndpoint } = await this.getOidcConfig();
58
+ const { userinfoEndpoint } = await this.getOidcConfig();
159
59
  const accessToken = await this.getAccessToken();
160
- if (!accessToken) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("fetch_user_info_failed");
161
- return (0, $4R6L3$logtojs.fetchUserInfo)(userinfoEndpoint, accessToken, this.adapter.requester);
60
+ if (!accessToken) {
61
+ throw new LogtoClientError('fetch_user_info_failed');
62
+ }
63
+ return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
162
64
  }
163
65
  async signIn(redirectUri, interactionMode) {
164
- const { appId: clientId , prompt: prompt , resources: resources , scopes: scopes } = this.logtoConfig;
165
- const { authorizationEndpoint: authorizationEndpoint } = await this.getOidcConfig();
66
+ const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;
67
+ const { authorizationEndpoint } = await this.getOidcConfig();
166
68
  const codeVerifier = this.adapter.generateCodeVerifier();
167
69
  const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);
168
70
  const state = this.adapter.generateState();
169
- const signInUri = (0, $4R6L3$logtojs.generateSignInUri)({
170
- authorizationEndpoint: authorizationEndpoint,
171
- clientId: clientId,
172
- redirectUri: redirectUri,
173
- codeChallenge: codeChallenge,
174
- state: state,
175
- scopes: scopes,
176
- resources: resources,
177
- prompt: prompt,
178
- interactionMode: interactionMode
179
- });
180
- await this.setSignInSession({
181
- redirectUri: redirectUri,
182
- codeVerifier: codeVerifier,
183
- state: state
71
+ const signInUri = generateSignInUri({
72
+ authorizationEndpoint,
73
+ clientId,
74
+ redirectUri,
75
+ codeChallenge,
76
+ state,
77
+ scopes,
78
+ resources,
79
+ prompt,
80
+ interactionMode,
184
81
  });
82
+ await this.setSignInSession({ redirectUri, codeVerifier, state });
185
83
  await this.setRefreshToken(null);
186
84
  await this.setIdToken(null);
187
85
  this.adapter.navigate(signInUri);
188
86
  }
189
87
  async isSignInRedirected(url) {
190
88
  const signInSession = await this.getSignInSession();
191
- if (!signInSession) return false;
192
- const { redirectUri: redirectUri } = signInSession;
193
- const { origin: origin , pathname: pathname } = new URL(url);
89
+ if (!signInSession) {
90
+ return false;
91
+ }
92
+ const { redirectUri } = signInSession;
93
+ const { origin, pathname } = new URL(url);
194
94
  return `${origin}${pathname}` === redirectUri;
195
95
  }
196
96
  async handleSignInCallback(callbackUri) {
197
- const { logtoConfig: logtoConfig , adapter: adapter } = this;
198
- const { requester: requester } = adapter;
97
+ const { logtoConfig, adapter } = this;
98
+ const { requester } = adapter;
199
99
  const signInSession = await this.getSignInSession();
200
- if (!signInSession) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("sign_in_session.not_found");
201
- const { redirectUri: redirectUri , state: state , codeVerifier: codeVerifier } = signInSession;
202
- const code = (0, $4R6L3$logtojs.verifyAndParseCodeFromCallbackUri)(callbackUri, redirectUri, state);
203
- const { appId: clientId } = logtoConfig;
204
- const { tokenEndpoint: tokenEndpoint } = await this.getOidcConfig();
205
- const codeTokenResponse = await (0, $4R6L3$logtojs.fetchTokenByAuthorizationCode)({
206
- clientId: clientId,
207
- tokenEndpoint: tokenEndpoint,
208
- redirectUri: redirectUri,
209
- codeVerifier: codeVerifier,
210
- code: code
100
+ if (!signInSession) {
101
+ throw new LogtoClientError('sign_in_session.not_found');
102
+ }
103
+ const { redirectUri, state, codeVerifier } = signInSession;
104
+ const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
105
+ const { appId: clientId } = logtoConfig;
106
+ const { tokenEndpoint } = await this.getOidcConfig();
107
+ const codeTokenResponse = await fetchTokenByAuthorizationCode({
108
+ clientId,
109
+ tokenEndpoint,
110
+ redirectUri,
111
+ codeVerifier,
112
+ code,
211
113
  }, requester);
212
114
  await this.verifyIdToken(codeTokenResponse.idToken);
213
115
  await this.saveCodeToken(codeTokenResponse);
214
116
  await this.setSignInSession(null);
215
117
  }
216
118
  async signOut(postLogoutRedirectUri) {
217
- const idToken = await this.getIdToken();
218
- if (!idToken) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("not_authenticated");
219
- const { appId: clientId } = this.logtoConfig;
220
- const { endSessionEndpoint: endSessionEndpoint , revocationEndpoint: revocationEndpoint } = await this.getOidcConfig();
119
+ const { appId: clientId } = this.logtoConfig;
120
+ const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();
221
121
  const refreshToken = await this.getRefreshToken();
222
- if (refreshToken) try {
223
- await (0, $4R6L3$logtojs.revoke)(revocationEndpoint, clientId, refreshToken, this.adapter.requester);
224
- } catch {
225
- // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
122
+ if (refreshToken) {
123
+ try {
124
+ await revoke(revocationEndpoint, clientId, refreshToken, this.adapter.requester);
125
+ }
126
+ catch {
127
+ // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
128
+ }
226
129
  }
227
- const url = (0, $4R6L3$logtojs.generateSignOutUri)({
228
- endSessionEndpoint: endSessionEndpoint,
229
- postLogoutRedirectUri: postLogoutRedirectUri,
230
- clientId: clientId
130
+ const url = generateSignOutUri({
131
+ endSessionEndpoint,
132
+ postLogoutRedirectUri,
133
+ clientId,
231
134
  });
232
135
  this.accessTokenMap.clear();
233
136
  await this.setRefreshToken(null);
234
137
  await this.setIdToken(null);
235
- await this.adapter.storage.removeItem("accessToken");
138
+ await this.adapter.storage.removeItem('accessToken');
236
139
  this.adapter.navigate(url);
237
140
  }
238
141
  async getSignInSession() {
239
- const jsonItem = await this.adapter.storage.getItem("signInSession");
240
- if (!jsonItem) return null;
142
+ const jsonItem = await this.adapter.storage.getItem('signInSession');
143
+ if (!jsonItem) {
144
+ return null;
145
+ }
241
146
  const item = JSON.parse(jsonItem);
242
- if (!(0, $6d3989f7f53311af$export$5d8adf6e063019de)(item)) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("sign_in_session.invalid");
147
+ if (!isLogtoSignInSessionItem(item)) {
148
+ throw new LogtoClientError('sign_in_session.invalid');
149
+ }
243
150
  return item;
244
151
  }
245
152
  async setSignInSession(logtoSignInSessionItem) {
246
153
  if (!logtoSignInSessionItem) {
247
- await this.adapter.storage.removeItem("signInSession");
154
+ await this.adapter.storage.removeItem('signInSession');
248
155
  return;
249
156
  }
250
157
  const jsonItem = JSON.stringify(logtoSignInSessionItem);
251
- await this.adapter.storage.setItem("signInSession", jsonItem);
158
+ await this.adapter.storage.setItem('signInSession', jsonItem);
252
159
  }
253
160
  async setIdToken(idToken) {
254
161
  if (!idToken) {
255
- await this.adapter.storage.removeItem("idToken");
162
+ await this.adapter.storage.removeItem('idToken');
256
163
  return;
257
164
  }
258
- await this.adapter.storage.setItem("idToken", idToken);
165
+ await this.adapter.storage.setItem('idToken', idToken);
259
166
  }
260
167
  async setRefreshToken(refreshToken) {
261
168
  if (!refreshToken) {
262
- await this.adapter.storage.removeItem("refreshToken");
169
+ await this.adapter.storage.removeItem('refreshToken');
263
170
  return;
264
171
  }
265
- await this.adapter.storage.setItem("refreshToken", refreshToken);
172
+ await this.adapter.storage.setItem('refreshToken', refreshToken);
266
173
  }
267
174
  async getAccessTokenByRefreshToken(resource) {
268
175
  const currentRefreshToken = await this.getRefreshToken();
269
- if (!currentRefreshToken) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("not_authenticated");
270
- const accessTokenKey = (0, $e2aabdbdb3cc09f0$export$8f595bd2a47bcea6)(resource);
271
- const { appId: clientId } = this.logtoConfig;
272
- const { tokenEndpoint: tokenEndpoint } = await this.getOidcConfig();
273
- const { accessToken: accessToken , refreshToken: refreshToken , idToken: idToken , scope: scope , expiresIn: expiresIn } = await (0, $4R6L3$logtojs.fetchTokenByRefreshToken)({
274
- clientId: clientId,
275
- tokenEndpoint: tokenEndpoint,
176
+ if (!currentRefreshToken) {
177
+ throw new LogtoClientError('not_authenticated');
178
+ }
179
+ const accessTokenKey = buildAccessTokenKey(resource);
180
+ const { appId: clientId } = this.logtoConfig;
181
+ const { tokenEndpoint } = await this.getOidcConfig();
182
+ const { accessToken, refreshToken, idToken, scope, expiresIn } = await fetchTokenByRefreshToken({
183
+ clientId,
184
+ tokenEndpoint,
276
185
  refreshToken: currentRefreshToken,
277
- resource: resource
186
+ resource,
278
187
  }, this.adapter.requester);
279
188
  this.accessTokenMap.set(accessTokenKey, {
280
189
  token: accessToken,
281
- scope: scope,
282
- expiresAt: Math.round(Date.now() / 1000) + expiresIn
190
+ scope,
191
+ expiresAt: Math.round(Date.now() / 1000) + expiresIn,
283
192
  });
284
193
  await this.saveAccessTokenMap();
285
194
  await this.setRefreshToken(refreshToken);
@@ -290,54 +199,56 @@ class $f73788ae50447ce9$export$2e2bcd8739ae039 {
290
199
  return accessToken;
291
200
  }
292
201
  async _getOidcConfig() {
293
- const { endpoint: endpoint } = this.logtoConfig;
294
- const discoveryEndpoint = (0, $e2aabdbdb3cc09f0$export$5d9c34f69c80822b)(endpoint);
295
- return (0, $4R6L3$logtojs.fetchOidcConfig)(discoveryEndpoint, this.adapter.requester);
202
+ const { endpoint } = this.logtoConfig;
203
+ const discoveryEndpoint = getDiscoveryEndpoint(endpoint);
204
+ return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);
296
205
  }
297
206
  async _getJwtVerifyGetKey() {
298
- const { jwksUri: jwksUri } = await this.getOidcConfig();
299
- return (0, $4R6L3$jose.createRemoteJWKSet)(new URL(jwksUri));
207
+ const { jwksUri } = await this.getOidcConfig();
208
+ return createRemoteJWKSet(new URL(jwksUri));
300
209
  }
301
210
  async verifyIdToken(idToken) {
302
- const { appId: appId } = this.logtoConfig;
303
- const { issuer: issuer } = await this.getOidcConfig();
211
+ const { appId } = this.logtoConfig;
212
+ const { issuer } = await this.getOidcConfig();
304
213
  const jwtVerifyGetKey = await this.getJwtVerifyGetKey();
305
- await (0, $4R6L3$logtojs.verifyIdToken)(idToken, appId, issuer, jwtVerifyGetKey);
214
+ await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);
306
215
  }
307
- async saveCodeToken({ refreshToken: refreshToken , idToken: idToken , scope: scope , accessToken: accessToken , expiresIn: expiresIn }) {
216
+ async saveCodeToken({ refreshToken, idToken, scope, accessToken, expiresIn, }) {
308
217
  await this.setRefreshToken(refreshToken ?? null);
309
218
  await this.setIdToken(idToken);
310
219
  // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
311
- const accessTokenKey = (0, $e2aabdbdb3cc09f0$export$8f595bd2a47bcea6)();
220
+ const accessTokenKey = buildAccessTokenKey();
312
221
  const expiresAt = Date.now() / 1000 + expiresIn;
313
- this.accessTokenMap.set(accessTokenKey, {
314
- token: accessToken,
315
- scope: scope,
316
- expiresAt: expiresAt
317
- });
222
+ this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });
318
223
  await this.saveAccessTokenMap();
319
224
  }
320
225
  async saveAccessTokenMap() {
321
226
  const data = {};
322
- for (const [key, accessToken] of this.accessTokenMap.entries())// eslint-disable-next-line @silverhand/fp/no-mutation
323
- data[key] = accessToken;
324
- await this.adapter.storage.setItem("accessToken", JSON.stringify(data));
227
+ for (const [key, accessToken] of this.accessTokenMap.entries()) {
228
+ // eslint-disable-next-line @silverhand/fp/no-mutation
229
+ data[key] = accessToken;
230
+ }
231
+ await this.adapter.storage.setItem('accessToken', JSON.stringify(data));
325
232
  }
326
233
  async loadAccessTokenMap() {
327
- const raw = await this.adapter.storage.getItem("accessToken");
328
- if (!raw) return;
234
+ const raw = await this.adapter.storage.getItem('accessToken');
235
+ if (!raw) {
236
+ return;
237
+ }
329
238
  try {
330
239
  const json = JSON.parse(raw);
331
- if (!(0, $6d3989f7f53311af$export$c12fab42a9a3e2a6)(json)) return;
240
+ if (!isLogtoAccessTokenMap(json)) {
241
+ return;
242
+ }
332
243
  this.accessTokenMap.clear();
333
- for (const [key, accessToken] of Object.entries(json))this.accessTokenMap.set(key, accessToken);
334
- } catch (error) {
244
+ for (const [key, accessToken] of Object.entries(json)) {
245
+ this.accessTokenMap.set(key, accessToken);
246
+ }
247
+ }
248
+ catch (error) {
335
249
  console.warn(error);
336
250
  }
337
251
  }
338
252
  }
339
- $parcel$exportWildcard(module.exports, $9166104b36889c59$exports);
340
- $parcel$exportWildcard(module.exports, $6d3989f7f53311af$exports);
341
-
342
253
 
343
- //# sourceMappingURL=index.js.map
254
+ export { LogtoClientError, LogtoClient as default, isLogtoAccessTokenMap, isLogtoSignInSessionItem };
@@ -0,0 +1 @@
1
+ export {};
package/lib/mock.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ /// <reference types="jest" />
2
+ import { Prompt } from '@logto/js';
3
+ import type { Nullable } from '@silverhand/essentials';
4
+ import type { Storage } from './adapter.js';
5
+ import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './index.js';
6
+ import LogtoClient from './index.js';
7
+ export declare const appId = "app_id_value";
8
+ export declare const endpoint = "https://logto.dev";
9
+ export declare class MockedStorage implements Storage {
10
+ private storage;
11
+ constructor(values?: Record<string, string>);
12
+ getItem(key: string): Promise<string | null>;
13
+ setItem(key: string, value: string): Promise<void>;
14
+ removeItem(key: string): Promise<void>;
15
+ reset(values: Record<string, string>): void;
16
+ }
17
+ export declare const authorizationEndpoint: string;
18
+ export declare const userinfoEndpoint: string;
19
+ export declare const tokenEndpoint: string;
20
+ export declare const endSessionEndpoint: string;
21
+ export declare const revocationEndpoint: string;
22
+ export declare const jwksUri: string;
23
+ export declare const issuer = "http://localhost:443/oidc";
24
+ export declare const redirectUri = "http://localhost:3000/callback";
25
+ export declare const postSignOutRedirectUri = "http://localhost:3000";
26
+ export declare const mockCodeChallenge = "code_challenge_value";
27
+ export declare const mockedCodeVerifier = "code_verifier_value";
28
+ export declare const mockedState = "state_value";
29
+ export declare const mockedSignInUri: string;
30
+ export declare const mockedSignInUriWithLoginPrompt: string;
31
+ export declare const mockedSignUpUri: string;
32
+ export declare const accessToken = "access_token_value";
33
+ export declare const refreshToken = "new_refresh_token_value";
34
+ export declare const idToken = "id_token_value";
35
+ export declare const currentUnixTimeStamp: number;
36
+ export declare const fetchOidcConfig: jest.Mock<Promise<{
37
+ authorizationEndpoint: string;
38
+ tokenEndpoint: string;
39
+ userinfoEndpoint: string;
40
+ endSessionEndpoint: string;
41
+ revocationEndpoint: string;
42
+ jwksUri: string;
43
+ issuer: string;
44
+ }>, [], any>;
45
+ export declare const requester: jest.Mock<any, any, any>;
46
+ export declare const failingRequester: jest.Mock<any, any, any>;
47
+ export declare const navigate: jest.Mock<any, any, any>;
48
+ export declare const generateCodeChallenge: jest.Mock<Promise<string>, [], any>;
49
+ export declare const generateCodeVerifier: jest.Mock<string, [], any>;
50
+ export declare const generateState: jest.Mock<string, [], any>;
51
+ export declare const createAdapters: () => {
52
+ requester: jest.Mock<any, any, any>;
53
+ storage: MockedStorage;
54
+ navigate: jest.Mock<any, any, any>;
55
+ generateCodeChallenge: jest.Mock<Promise<string>, [], any>;
56
+ generateCodeVerifier: jest.Mock<string, [], any>;
57
+ generateState: jest.Mock<string, [], any>;
58
+ };
59
+ export declare const createClient: (prompt?: Prompt, storage?: MockedStorage) => LogtoClient;
60
+ /**
61
+ * Make LogtoClient.signInSession accessible for test
62
+ */
63
+ export declare class LogtoClientSignInSessionAccessor extends LogtoClient {
64
+ getLogtoConfig(): Nullable<LogtoConfig>;
65
+ getSignInSessionItem(): Promise<Nullable<LogtoSignInSessionItem>>;
66
+ setSignInSessionItem(item: Nullable<LogtoSignInSessionItem>): Promise<void>;
67
+ getAccessTokenMap(): Map<string, AccessToken>;
68
+ }
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var js = require('@logto/js');
4
+
5
+ const isLogtoSignInSessionItem = (data) => {
6
+ if (!js.isArbitraryObject(data)) {
7
+ return false;
8
+ }
9
+ return ['redirectUri', 'codeVerifier', 'state'].every((key) => typeof data[key] === 'string');
10
+ };
11
+ const isLogtoAccessTokenMap = (data) => {
12
+ if (!js.isArbitraryObject(data)) {
13
+ return false;
14
+ }
15
+ return Object.values(data).every((value) => {
16
+ if (!js.isArbitraryObject(value)) {
17
+ return false;
18
+ }
19
+ return (typeof value.token === 'string' &&
20
+ typeof value.scope === 'string' &&
21
+ typeof value.expiresAt === 'number');
22
+ });
23
+ };
24
+
25
+ exports.isLogtoAccessTokenMap = isLogtoAccessTokenMap;
26
+ exports.isLogtoSignInSessionItem = isLogtoSignInSessionItem;
@@ -0,0 +1,21 @@
1
+ import type { Prompt } from '@logto/js';
2
+ export type LogtoConfig = {
3
+ endpoint: string;
4
+ appId: string;
5
+ appSecret?: string;
6
+ scopes?: string[];
7
+ resources?: string[];
8
+ prompt?: Prompt;
9
+ };
10
+ export type AccessToken = {
11
+ token: string;
12
+ scope: string;
13
+ expiresAt: number;
14
+ };
15
+ export declare const isLogtoSignInSessionItem: (data: unknown) => data is LogtoSignInSessionItem;
16
+ export declare const isLogtoAccessTokenMap: (data: unknown) => data is Record<string, AccessToken>;
17
+ export type LogtoSignInSessionItem = {
18
+ redirectUri: string;
19
+ codeVerifier: string;
20
+ state: string;
21
+ };
@@ -0,0 +1,23 @@
1
+ import { isArbitraryObject } from '@logto/js';
2
+
3
+ const isLogtoSignInSessionItem = (data) => {
4
+ if (!isArbitraryObject(data)) {
5
+ return false;
6
+ }
7
+ return ['redirectUri', 'codeVerifier', 'state'].every((key) => typeof data[key] === 'string');
8
+ };
9
+ const isLogtoAccessTokenMap = (data) => {
10
+ if (!isArbitraryObject(data)) {
11
+ return false;
12
+ }
13
+ return Object.values(data).every((value) => {
14
+ if (!isArbitraryObject(value)) {
15
+ return false;
16
+ }
17
+ return (typeof value.token === 'string' &&
18
+ typeof value.scope === 'string' &&
19
+ typeof value.expiresAt === 'number');
20
+ });
21
+ };
22
+
23
+ export { isLogtoAccessTokenMap, isLogtoSignInSessionItem };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var js = require('@logto/js');
4
+
5
+ const buildAccessTokenKey = (resource = '', scopes = []) => `${scopes.slice().sort().join(' ')}@${resource}`;
6
+ const getDiscoveryEndpoint = (endpoint) => new URL(js.discoveryPath, endpoint).toString();
7
+
8
+ exports.buildAccessTokenKey = buildAccessTokenKey;
9
+ exports.getDiscoveryEndpoint = getDiscoveryEndpoint;
@@ -0,0 +1,3 @@
1
+ export * from './requester.js';
2
+ export declare const buildAccessTokenKey: (resource?: string, scopes?: string[]) => string;
3
+ export declare const getDiscoveryEndpoint: (endpoint: string) => string;
@@ -0,0 +1,6 @@
1
+ import { discoveryPath } from '@logto/js';
2
+
3
+ const buildAccessTokenKey = (resource = '', scopes = []) => `${scopes.slice().sort().join(' ')}@${resource}`;
4
+ const getDiscoveryEndpoint = (endpoint) => new URL(discoveryPath, endpoint).toString();
5
+
6
+ export { buildAccessTokenKey, getDiscoveryEndpoint };
@@ -0,0 +1 @@
1
+ export {};