@logto/client
Advanced tools
Comparing version 2.1.0 to 2.2.0
import { type IdTokenClaims, type UserInfoResponse, type InteractionMode, type AccessTokenClaims } from '@logto/js'; | ||
import type { Nullable } from '@silverhand/essentials'; | ||
import type { ClientAdapter } from './adapter.js'; | ||
import { type Nullable } from '@silverhand/essentials'; | ||
import { type JWTVerifyGetKey } from 'jose'; | ||
import { ClientAdapterInstance, type ClientAdapter } from './adapter/index.js'; | ||
import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './types/index.js'; | ||
@@ -8,10 +9,20 @@ export type { IdTokenClaims, LogtoErrorCode, UserInfoResponse, InteractionMode } from '@logto/js'; | ||
export * from './errors.js'; | ||
export type { Storage, StorageKey, ClientAdapter } from './adapter.js'; | ||
export type { Storage, StorageKey, ClientAdapter } from './adapter/index.js'; | ||
export { PersistKey, CacheKey } from './adapter/index.js'; | ||
export { createRequester } from './utils/index.js'; | ||
export * from './types/index.js'; | ||
export default class LogtoClient { | ||
#private; | ||
protected readonly logtoConfig: LogtoConfig; | ||
protected readonly getOidcConfig: typeof this._getOidcConfig; | ||
protected readonly getJwtVerifyGetKey: (...args: unknown[]) => Promise<(protectedHeader?: import("jose").JWSHeaderParameters | undefined, token?: import("jose").FlattenedJWSInput | undefined) => Promise<import("jose").KeyLike>>; | ||
protected readonly adapter: ClientAdapter; | ||
protected readonly getOidcConfig: (this: unknown) => Promise<import("@silverhand/essentials").KeysToCamelCase<{ | ||
authorization_endpoint: string; | ||
token_endpoint: string; | ||
userinfo_endpoint: string; | ||
end_session_endpoint: string; | ||
revocation_endpoint: string; | ||
jwks_uri: string; | ||
issuer: string; | ||
}>>; | ||
protected readonly getJwtVerifyGetKey: (...args: unknown[]) => Promise<JWTVerifyGetKey>; | ||
protected readonly adapter: ClientAdapterInstance; | ||
protected readonly accessTokenMap: Map<string, AccessToken>; | ||
@@ -31,8 +42,6 @@ constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter); | ||
protected getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>>; | ||
protected setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>): Promise<void>; | ||
protected setSignInSession(value: Nullable<LogtoSignInSessionItem>): Promise<void>; | ||
private setIdToken; | ||
private setRefreshToken; | ||
private getAccessTokenByRefreshToken; | ||
private _getOidcConfig; | ||
private _getJwtVerifyGetKey; | ||
private verifyIdToken; | ||
@@ -39,0 +48,0 @@ private saveCodeToken; |
@@ -1,8 +0,12 @@ | ||
import { Prompt, withDefaultScopes, decodeIdToken, decodeAccessToken, fetchUserInfo, generateSignInUri, verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode, revoke, generateSignOutUri, fetchTokenByRefreshToken, fetchOidcConfig, verifyIdToken } from '@logto/js'; | ||
import { Prompt, withDefaultScopes, decodeIdToken, decodeAccessToken, fetchUserInfo, generateSignInUri, verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode, revoke, generateSignOutUri, fetchTokenByRefreshToken, verifyIdToken, fetchOidcConfig } from '@logto/js'; | ||
export { LogtoError, LogtoRequestError, OidcError, Prompt, ReservedScope, UserScope } from '@logto/js'; | ||
import { createRemoteJWKSet } from 'jose'; | ||
import { ClientAdapterInstance } from './adapter/index.js'; | ||
import { LogtoClientError } from './errors.js'; | ||
import { CachedRemoteJwkSet } from './remote-jwk-set.js'; | ||
import { isLogtoSignInSessionItem, isLogtoAccessTokenMap } from './types/index.js'; | ||
import { buildAccessTokenKey, getDiscoveryEndpoint } from './utils/index.js'; | ||
import { memoize } from './utils/memoize.js'; | ||
import { once } from './utils/once.js'; | ||
import { PersistKey, CacheKey } from './adapter/types.js'; | ||
export { createRequester } from './utils/requester.js'; | ||
@@ -12,4 +16,4 @@ | ||
constructor(logtoConfig, adapter) { | ||
this.getOidcConfig = once(this._getOidcConfig); | ||
this.getJwtVerifyGetKey = once(this._getJwtVerifyGetKey); | ||
this.getOidcConfig = memoize(this.#getOidcConfig); | ||
this.getJwtVerifyGetKey = once(this.#getJwtVerifyGetKey); | ||
this.accessTokenMap = new Map(); | ||
@@ -21,3 +25,3 @@ this.logtoConfig = { | ||
}; | ||
this.adapter = adapter; | ||
this.adapter = new ClientAdapterInstance(adapter); | ||
void this.loadAccessTokenMap(); | ||
@@ -158,23 +162,10 @@ } | ||
} | ||
async setSignInSession(logtoSignInSessionItem) { | ||
if (!logtoSignInSessionItem) { | ||
await this.adapter.storage.removeItem('signInSession'); | ||
return; | ||
} | ||
const jsonItem = JSON.stringify(logtoSignInSessionItem); | ||
await this.adapter.storage.setItem('signInSession', jsonItem); | ||
async setSignInSession(value) { | ||
return this.adapter.setStorageItem(PersistKey.SignInSession, value && JSON.stringify(value)); | ||
} | ||
async setIdToken(idToken) { | ||
if (!idToken) { | ||
await this.adapter.storage.removeItem('idToken'); | ||
return; | ||
} | ||
await this.adapter.storage.setItem('idToken', idToken); | ||
async setIdToken(value) { | ||
return this.adapter.setStorageItem(PersistKey.IdToken, value); | ||
} | ||
async setRefreshToken(refreshToken) { | ||
if (!refreshToken) { | ||
await this.adapter.storage.removeItem('refreshToken'); | ||
return; | ||
} | ||
await this.adapter.storage.setItem('refreshToken', refreshToken); | ||
async setRefreshToken(value) { | ||
return this.adapter.setStorageItem(PersistKey.RefreshToken, value); | ||
} | ||
@@ -208,11 +199,2 @@ async getAccessTokenByRefreshToken(resource) { | ||
} | ||
async _getOidcConfig() { | ||
const { endpoint } = this.logtoConfig; | ||
const discoveryEndpoint = getDiscoveryEndpoint(endpoint); | ||
return fetchOidcConfig(discoveryEndpoint, this.adapter.requester); | ||
} | ||
async _getJwtVerifyGetKey() { | ||
const { jwksUri } = await this.getOidcConfig(); | ||
return createRemoteJWKSet(new URL(jwksUri)); | ||
} | ||
async verifyIdToken(idToken) { | ||
@@ -260,4 +242,17 @@ const { appId } = this.logtoConfig; | ||
} | ||
async #getOidcConfig() { | ||
return this.adapter.getWithCache(CacheKey.OpenidConfig, async () => { | ||
return fetchOidcConfig(getDiscoveryEndpoint(this.logtoConfig.endpoint), this.adapter.requester); | ||
}); | ||
} | ||
async #getJwtVerifyGetKey() { | ||
const { jwksUri } = await this.getOidcConfig(); | ||
if (!this.adapter.unstable_cache) { | ||
return createRemoteJWKSet(new URL(jwksUri)); | ||
} | ||
const cachedJwkSet = new CachedRemoteJwkSet(new URL(jwksUri), this.adapter); | ||
return async (...args) => cachedJwkSet.getKey(...args); | ||
} | ||
} | ||
export { LogtoClientError, LogtoClient as default, isLogtoAccessTokenMap, isLogtoSignInSessionItem }; | ||
export { CacheKey, LogtoClientError, PersistKey, LogtoClient as default, isLogtoAccessTokenMap, isLogtoSignInSessionItem }; |
/// <reference types="jest" /> | ||
import { Prompt } from '@logto/js'; | ||
import type { Nullable } from '@silverhand/essentials'; | ||
import type { Storage } from './adapter.js'; | ||
import { type Nullable } from '@silverhand/essentials'; | ||
import type { Storage } from './adapter/index.js'; | ||
import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './index.js'; | ||
@@ -9,3 +9,3 @@ import LogtoClient from './index.js'; | ||
export declare const endpoint = "https://logto.dev"; | ||
export declare class MockedStorage implements Storage { | ||
export declare class MockedStorage implements Storage<string> { | ||
private storage; | ||
@@ -37,2 +37,11 @@ constructor(values?: Record<string, string>); | ||
export declare const currentUnixTimeStamp: number; | ||
export declare const mockFetchOidcConfig: (delay?: number) => jest.Mock<Promise<{ | ||
authorizationEndpoint: string; | ||
tokenEndpoint: string; | ||
userinfoEndpoint: string; | ||
endSessionEndpoint: string; | ||
revocationEndpoint: string; | ||
jwksUri: string; | ||
issuer: string; | ||
}>, [], any>; | ||
export declare const fetchOidcConfig: jest.Mock<Promise<{ | ||
@@ -53,5 +62,6 @@ authorizationEndpoint: string; | ||
export declare const generateState: jest.Mock<string, [], any>; | ||
export declare const createAdapters: () => { | ||
export declare const createAdapters: (withCache?: boolean) => { | ||
requester: jest.Mock<any, any, any>; | ||
storage: MockedStorage; | ||
unstable_cache: import("@silverhand/essentials").Optional<MockedStorage>; | ||
navigate: jest.Mock<any, any, any>; | ||
@@ -62,7 +72,17 @@ generateCodeChallenge: jest.Mock<Promise<string>, [], any>; | ||
}; | ||
export declare const createClient: (prompt?: Prompt, storage?: MockedStorage) => LogtoClient; | ||
export declare const createClient: (prompt?: Prompt, storage?: MockedStorage, withCache?: boolean) => LogtoClientWithAccessors; | ||
/** | ||
* Make LogtoClient.signInSession accessible for test | ||
* Make protected fields accessible for test | ||
*/ | ||
export declare class LogtoClientSignInSessionAccessor extends LogtoClient { | ||
export declare class LogtoClientWithAccessors extends LogtoClient { | ||
runGetOidcConfig(): Promise<import("@silverhand/essentials").KeysToCamelCase<{ | ||
authorization_endpoint: string; | ||
token_endpoint: string; | ||
userinfo_endpoint: string; | ||
end_session_endpoint: string; | ||
revocation_endpoint: string; | ||
jwks_uri: string; | ||
issuer: string; | ||
}>>; | ||
runGetJwtVerifyGetKey(): Promise<import("jose").JWTVerifyGetKey>; | ||
getLogtoConfig(): Nullable<LogtoConfig>; | ||
@@ -69,0 +89,0 @@ getSignInSessionItem(): Promise<Nullable<LogtoSignInSessionItem>>; |
{ | ||
"name": "@logto/client", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.cjs", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
67086
44
1573
2