@logto/client 1.0.0-beta.0 → 1.0.0-beta.2

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
@@ -34,6 +34,7 @@ export class LogtoClientError extends Error {
34
34
  export type LogtoConfig = {
35
35
  endpoint: string;
36
36
  appId: string;
37
+ appSecret?: string;
37
38
  scopes?: string[];
38
39
  resources?: string[];
39
40
  prompt?: Prompt;
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/client/src/src/adapter.ts","packages/client/src/src/errors.ts","packages/client/src/src/types/index.ts","packages/client/src/src/utils/requester.ts","packages/client/src/src/utils/index.ts","packages/client/src/src/index.ts","packages/client/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,"import {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert } from 'superstruct';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n LogtoAccessTokenMapSchema,\n LogtoConfig,\n LogtoSignInSessionItem,\n LogtoSignInSessionItemSchema,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';\nexport * from './errors';\nexport type { Storage, StorageKey, ClientAdapter } from './adapter';\nexport { createRequester } from './utils';\nexport * from './types';\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly adapter: ClientAdapter;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n this._idToken = this.adapter.storage.getItem('idToken');\n\n if (this.logtoConfig.persistAccessToken) {\n this.loadAccessTokenMap();\n }\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n get refreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n if (!idToken) {\n this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n this.adapter.storage.setItem('idToken', idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = this.adapter.generateCodeVerifier();\n const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);\n const state = this.adapter.generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, adapter } = this;\n const { requester } = adapter;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.adapter.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.adapter.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n this.saveAccessTokenMap();\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n this.saveAccessTokenMap();\n }\n\n private saveAccessTokenMap() {\n if (!this.logtoConfig.persistAccessToken) {\n return;\n }\n\n const data: Record<string, AccessToken> = {};\n\n for (const [key, accessToken] of this.accessTokenMap.entries()) {\n // eslint-disable-next-line @silverhand/fp/no-mutation\n data[key] = accessToken;\n }\n\n this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private loadAccessTokenMap() {\n const raw = this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n assert(json, LogtoAccessTokenMapSchema);\n this.accessTokenMap.clear();\n\n for (const [key, accessToken] of Object.entries(json)) {\n this.accessTokenMap.set(key, accessToken);\n }\n } catch {}\n }\n}\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":"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","sources":["packages/client/src/src/adapter.ts","packages/client/src/src/errors.ts","packages/client/src/src/types/index.ts","packages/client/src/src/utils/requester.ts","packages/client/src/src/utils/index.ts","packages/client/src/src/index.ts","packages/client/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,"import {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert } from 'superstruct';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n LogtoAccessTokenMapSchema,\n LogtoConfig,\n LogtoSignInSessionItem,\n LogtoSignInSessionItemSchema,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';\nexport * from './errors';\nexport type { Storage, StorageKey, ClientAdapter } from './adapter';\nexport { createRequester } from './utils';\nexport * from './types';\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly adapter: ClientAdapter;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n this._idToken = this.adapter.storage.getItem('idToken');\n\n if (this.logtoConfig.persistAccessToken) {\n this.loadAccessTokenMap();\n }\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n get refreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n if (!idToken) {\n this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n this.adapter.storage.setItem('idToken', idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = this.adapter.generateCodeVerifier();\n const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);\n const state = this.adapter.generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, adapter } = this;\n const { requester } = adapter;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.adapter.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.adapter.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n this.saveAccessTokenMap();\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n this.saveAccessTokenMap();\n }\n\n private saveAccessTokenMap() {\n if (!this.logtoConfig.persistAccessToken) {\n return;\n }\n\n const data: Record<string, AccessToken> = {};\n\n for (const [key, accessToken] of this.accessTokenMap.entries()) {\n // eslint-disable-next-line @silverhand/fp/no-mutation\n data[key] = accessToken;\n }\n\n this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private loadAccessTokenMap() {\n const raw = this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n assert(json, LogtoAccessTokenMapSchema);\n this.accessTokenMap.clear();\n\n for (const [key, accessToken] of Object.entries(json)) {\n this.accessTokenMap.set(key, accessToken);\n }\n } catch {}\n }\n}\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/lib/index.js CHANGED
@@ -95,8 +95,10 @@ const $b455f57f80fbf6bf$export$8d54726fdbf08e0a = (fetchFunction)=>{
95
95
  return async (...args)=>{
96
96
  const response = await fetchFunction(...args);
97
97
  if (!response.ok) {
98
+ const responseJson = await response.json();
99
+ if (!(0, $4R6L3$logtojs.logtoRequestErrorSchema).is(responseJson)) throw new (0, $4R6L3$logtojs.LogtoError)("unexpected_response_error", responseJson);
98
100
  // Expected request error from server
99
- const { code: code , message: message } = await response.json();
101
+ const { code: code , message: message } = responseJson;
100
102
  throw new (0, $4R6L3$logtojs.LogtoRequestError)(code, message);
101
103
  }
102
104
  return response.json();
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/client/src/index.ts","packages/client/src/errors.ts","packages/client/src/types/index.ts","packages/client/src/utils/index.ts","packages/client/src/utils/requester.ts"],"sourcesContent":["import {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert } from 'superstruct';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n LogtoAccessTokenMapSchema,\n LogtoConfig,\n LogtoSignInSessionItem,\n LogtoSignInSessionItemSchema,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';\nexport * from './errors';\nexport type { Storage, StorageKey, ClientAdapter } from './adapter';\nexport { createRequester } from './utils';\nexport * from './types';\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly adapter: ClientAdapter;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n this._idToken = this.adapter.storage.getItem('idToken');\n\n if (this.logtoConfig.persistAccessToken) {\n this.loadAccessTokenMap();\n }\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n get refreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n if (!idToken) {\n this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n this.adapter.storage.setItem('idToken', idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = this.adapter.generateCodeVerifier();\n const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);\n const state = this.adapter.generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, adapter } = this;\n const { requester } = adapter;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.adapter.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.adapter.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n this.saveAccessTokenMap();\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n this.saveAccessTokenMap();\n }\n\n private saveAccessTokenMap() {\n if (!this.logtoConfig.persistAccessToken) {\n return;\n }\n\n const data: Record<string, AccessToken> = {};\n\n for (const [key, accessToken] of this.accessTokenMap.entries()) {\n // eslint-disable-next-line @silverhand/fp/no-mutation\n data[key] = accessToken;\n }\n\n this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private loadAccessTokenMap() {\n const raw = this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n assert(json, LogtoAccessTokenMapSchema);\n this.accessTokenMap.clear();\n\n for (const [key, accessToken] of Object.entries(json)) {\n this.accessTokenMap.set(key, accessToken);\n }\n } catch {}\n }\n}\n","import { NormalizeKeyPaths } from '@silverhand/essentials';\nimport get from 'lodash.get';\n\nconst logtoClientErrorCodes = Object.freeze({\n sign_in_session: {\n invalid: 'Invalid sign-in session.',\n not_found: 'Sign-in session not found.',\n },\n not_authenticated: 'Not authenticated.',\n get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',\n invalid_id_token: 'Invalid id token.',\n});\n\nexport type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;\n\nconst getMessageByErrorCode = (errorCode: LogtoClientErrorCode): string => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const message = get(logtoClientErrorCodes, errorCode);\n\n if (typeof message === 'string') {\n return message;\n }\n\n return errorCode;\n};\n\nexport class LogtoClientError extends Error {\n code: LogtoClientErrorCode;\n data: unknown;\n\n constructor(code: LogtoClientErrorCode, data?: unknown) {\n super(getMessageByErrorCode(code));\n this.code = code;\n this.data = data;\n }\n}\n","import { Prompt } from '@logto/js';\nimport { Infer, number, record, string, type } from 'superstruct';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n persistAccessToken?: boolean;\n};\n\nexport const AccessTokenSchema = type({\n token: string(),\n scope: string(),\n expiresAt: number(),\n});\n\nexport type AccessToken = Infer<typeof AccessTokenSchema>;\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport const LogtoAccessTokenMapSchema = record(string(), AccessTokenSchema);\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n","import { discoveryPath } from '@logto/js';\n\nexport * from './requester';\n\nexport const buildAccessTokenKey = (resource = '', scopes: string[] = []): string =>\n `${scopes.slice().sort().join(' ')}@${resource}`;\n\nexport const getDiscoveryEndpoint = (endpoint: string): string =>\n new URL(discoveryPath, endpoint).toString();\n","import { LogtoRequestError, LogtoRequestErrorBody, Requester } from '@logto/js';\n\nexport const createRequester = (fetchFunction: typeof fetch): Requester => {\n return async <T>(...args: Parameters<typeof fetch>): Promise<T> => {\n const response = await fetchFunction(...args);\n\n if (!response.ok) {\n // Expected request error from server\n const { code, message } = await response.json<LogtoRequestErrorBody>();\n throw new LogtoRequestError(code, message);\n }\n\n return response.json<T>();\n };\n};\n"],"names":[],"version":3,"file":"index.js.map"}
1
+ {"mappings":"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","sources":["packages/client/src/index.ts","packages/client/src/errors.ts","packages/client/src/types/index.ts","packages/client/src/utils/index.ts","packages/client/src/utils/requester.ts"],"sourcesContent":["import {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert } from 'superstruct';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n LogtoAccessTokenMapSchema,\n LogtoConfig,\n LogtoSignInSessionItem,\n LogtoSignInSessionItemSchema,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';\nexport * from './errors';\nexport type { Storage, StorageKey, ClientAdapter } from './adapter';\nexport { createRequester } from './utils';\nexport * from './types';\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly adapter: ClientAdapter;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n this._idToken = this.adapter.storage.getItem('idToken');\n\n if (this.logtoConfig.persistAccessToken) {\n this.loadAccessTokenMap();\n }\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n get refreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n if (!idToken) {\n this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n this.adapter.storage.setItem('idToken', idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = this.adapter.generateCodeVerifier();\n const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);\n const state = this.adapter.generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, adapter } = this;\n const { requester } = adapter;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.adapter.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.adapter.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n this.saveAccessTokenMap();\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n this.saveAccessTokenMap();\n }\n\n private saveAccessTokenMap() {\n if (!this.logtoConfig.persistAccessToken) {\n return;\n }\n\n const data: Record<string, AccessToken> = {};\n\n for (const [key, accessToken] of this.accessTokenMap.entries()) {\n // eslint-disable-next-line @silverhand/fp/no-mutation\n data[key] = accessToken;\n }\n\n this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private loadAccessTokenMap() {\n const raw = this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n assert(json, LogtoAccessTokenMapSchema);\n this.accessTokenMap.clear();\n\n for (const [key, accessToken] of Object.entries(json)) {\n this.accessTokenMap.set(key, accessToken);\n }\n } catch {}\n }\n}\n","import { NormalizeKeyPaths } from '@silverhand/essentials';\nimport get from 'lodash.get';\n\nconst logtoClientErrorCodes = Object.freeze({\n sign_in_session: {\n invalid: 'Invalid sign-in session.',\n not_found: 'Sign-in session not found.',\n },\n not_authenticated: 'Not authenticated.',\n get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',\n invalid_id_token: 'Invalid id token.',\n});\n\nexport type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;\n\nconst getMessageByErrorCode = (errorCode: LogtoClientErrorCode): string => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const message = get(logtoClientErrorCodes, errorCode);\n\n if (typeof message === 'string') {\n return message;\n }\n\n return errorCode;\n};\n\nexport class LogtoClientError extends Error {\n code: LogtoClientErrorCode;\n data: unknown;\n\n constructor(code: LogtoClientErrorCode, data?: unknown) {\n super(getMessageByErrorCode(code));\n this.code = code;\n this.data = data;\n }\n}\n","import { Prompt } from '@logto/js';\nimport { Infer, number, record, string, type } from 'superstruct';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n appSecret?: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n persistAccessToken?: boolean;\n};\n\nexport const AccessTokenSchema = type({\n token: string(),\n scope: string(),\n expiresAt: number(),\n});\n\nexport type AccessToken = Infer<typeof AccessTokenSchema>;\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport const LogtoAccessTokenMapSchema = record(string(), AccessTokenSchema);\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n","import { discoveryPath } from '@logto/js';\n\nexport * from './requester';\n\nexport const buildAccessTokenKey = (resource = '', scopes: string[] = []): string =>\n `${scopes.slice().sort().join(' ')}@${resource}`;\n\nexport const getDiscoveryEndpoint = (endpoint: string): string =>\n new URL(discoveryPath, endpoint).toString();\n","import { LogtoError, LogtoRequestError, logtoRequestErrorSchema, Requester } from '@logto/js';\n\nexport const createRequester = (fetchFunction: typeof fetch): Requester => {\n return async <T>(...args: Parameters<typeof fetch>): Promise<T> => {\n const response = await fetchFunction(...args);\n\n if (!response.ok) {\n const responseJson = await response.json();\n\n if (!logtoRequestErrorSchema.is(responseJson)) {\n throw new LogtoError('unexpected_response_error', responseJson);\n }\n\n // Expected request error from server\n const { code, message } = responseJson;\n throw new LogtoRequestError(code, message);\n }\n\n return response.json();\n };\n};\n"],"names":[],"version":3,"file":"index.js.map"}
package/lib/module.js CHANGED
@@ -1,4 +1,4 @@
1
- import {Prompt as $19775a679e2952df$import$5548085c5b0a2ee3$83716a4aa1642908, withReservedScopes as $kqBTI$withReservedScopes, decodeIdToken as $kqBTI$decodeIdToken, generateSignInUri as $kqBTI$generateSignInUri, verifyAndParseCodeFromCallbackUri as $kqBTI$verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode as $kqBTI$fetchTokenByAuthorizationCode, revoke as $kqBTI$revoke, generateSignOutUri as $kqBTI$generateSignOutUri, fetchTokenByRefreshToken as $kqBTI$fetchTokenByRefreshToken, fetchOidcConfig as $kqBTI$fetchOidcConfig, verifyIdToken as $kqBTI$verifyIdToken, LogtoError as $19775a679e2952df$re_export$LogtoError, OidcError as $19775a679e2952df$re_export$OidcError, LogtoRequestError as $19775a679e2952df$re_export$LogtoRequestError, discoveryPath as $kqBTI$discoveryPath} from "@logto/js";
1
+ import {Prompt as $19775a679e2952df$import$5548085c5b0a2ee3$83716a4aa1642908, withReservedScopes as $kqBTI$withReservedScopes, decodeIdToken as $kqBTI$decodeIdToken, generateSignInUri as $kqBTI$generateSignInUri, verifyAndParseCodeFromCallbackUri as $kqBTI$verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode as $kqBTI$fetchTokenByAuthorizationCode, revoke as $kqBTI$revoke, generateSignOutUri as $kqBTI$generateSignOutUri, fetchTokenByRefreshToken as $kqBTI$fetchTokenByRefreshToken, fetchOidcConfig as $kqBTI$fetchOidcConfig, verifyIdToken as $kqBTI$verifyIdToken, LogtoError as $19775a679e2952df$re_export$LogtoError, OidcError as $19775a679e2952df$re_export$OidcError, LogtoRequestError as $19775a679e2952df$re_export$LogtoRequestError, discoveryPath as $kqBTI$discoveryPath, logtoRequestErrorSchema as $kqBTI$logtoRequestErrorSchema} from "@logto/js";
2
2
  import {createRemoteJWKSet as $kqBTI$createRemoteJWKSet} from "jose";
3
3
  import $kqBTI$lodashonce from "lodash.once";
4
4
  import {assert as $kqBTI$assert, type as $kqBTI$type, string as $kqBTI$string, number as $kqBTI$number, record as $kqBTI$record} from "superstruct";
@@ -64,8 +64,10 @@ const $8449a5dbad0d6387$export$8d54726fdbf08e0a = (fetchFunction)=>{
64
64
  return async (...args)=>{
65
65
  const response = await fetchFunction(...args);
66
66
  if (!response.ok) {
67
+ const responseJson = await response.json();
68
+ if (!(0, $kqBTI$logtoRequestErrorSchema).is(responseJson)) throw new (0, $19775a679e2952df$re_export$LogtoError)("unexpected_response_error", responseJson);
67
69
  // Expected request error from server
68
- const { code: code , message: message } = await response.json();
70
+ const { code: code , message: message } = responseJson;
69
71
  throw new (0, $19775a679e2952df$re_export$LogtoRequestError)(code, message);
70
72
  }
71
73
  return response.json();
package/lib/module.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;AAAA;;;;;;;ACAA;AAGA,MAAM,2CAAqB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,eAAe,EAAE;QACf,OAAO,EAAE,0BAA0B;QACnC,SAAS,EAAE,4BAA4B;KACxC;IACD,iBAAiB,EAAE,oBAAoB;IACvC,wCAAwC,EAAE,8CAA8C;IACxF,gBAAgB,EAAE,mBAAmB;CACtC,CAAC,AAAC;AAIH,MAAM,2CAAqB,GAAG,CAAC,SAA+B,GAAa;IACzE,mEAAmE;IACnE,MAAM,OAAO,GAAG,CAAA,GAAA,gBAAG,CAAA,CAAC,2CAAqB,EAAE,SAAS,CAAC,AAAC;IAEtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAC7B,OAAO,OAAO,CAAC;IAGjB,OAAO,SAAS,CAAC;CAClB,AAAC;AAEK,MAAM,yCAAgB,SAAS,KAAK;IAIzC,YAAY,IAA0B,EAAE,IAAc,CAAE;QACtD,KAAK,CAAC,2CAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;KAClB;CACF;;;;;;;;ACnCD;AAYO,MAAM,yCAAiB,GAAG,CAAA,GAAA,WAAI,CAAA,CAAC;IACpC,KAAK,EAAE,CAAA,GAAA,aAAM,CAAA,EAAE;IACf,KAAK,EAAE,CAAA,GAAA,aAAM,CAAA,EAAE;IACf,SAAS,EAAE,CAAA,GAAA,aAAM,CAAA,EAAE;CACpB,CAAC,AAAC;AAII,MAAM,yCAA4B,GAAG,CAAA,GAAA,WAAI,CAAA,CAAC;IAC/C,WAAW,EAAE,CAAA,GAAA,aAAM,CAAA,EAAE;IACrB,YAAY,EAAE,CAAA,GAAA,aAAM,CAAA,EAAE;IACtB,KAAK,EAAE,CAAA,GAAA,aAAM,CAAA,EAAE;CAChB,CAAC,AAAC;AAEI,MAAM,yCAAyB,GAAG,CAAA,GAAA,aAAM,CAAA,CAAC,CAAA,GAAA,aAAM,CAAA,EAAE,EAAE,yCAAiB,CAAC,AAAC;;;AC1B7E;ACAA;AAEO,MAAM,yCAAe,GAAG,CAAC,aAA2B,GAAgB;IACzE,OAAO,OAAU,GAAG,IAAI,AAA0B,GAAiB;QACjE,MAAM,QAAQ,GAAG,MAAM,aAAa,IAAI,IAAI,CAAC,AAAC;QAE9C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;YAChB,qCAAqC;YACrC,MAAM,QAAE,IAAI,CAAA,WAAE,OAAO,CAAA,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyB,AAAC;YACvE,MAAM,IAAI,CAAA,GAAA,6CAAiB,CAAA,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;SAC5C;QAED,OAAO,QAAQ,CAAC,IAAI,EAAK,CAAC;KAC3B,CAAC;CACH,AAAC;;;ADVK,MAAM,yCAAmB,GAAG,CAAC,QAAQ,GAAG,EAAE,EAAE,MAAgB,GAAG,EAAE,GACtE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,AAAC;AAE5C,MAAM,yCAAoB,GAAG,CAAC,QAAgB,GACnD,IAAI,GAAG,CAAC,CAAA,GAAA,oBAAa,CAAA,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,AAAC;;;;;;;AH8B/B;IAEb,AAAmB,aAAa,GAAG,CAAA,GAAA,iBAAI,CAAA,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7D,AAAmB,kBAAkB,GAAG,CAAA,GAAA,iBAAI,CAAA,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAIvE,AAAmB,cAAc,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEnE,AAAiB,wBAAwB,GAAG,IAAI,GAAG,EAA2B,CAAC;IAG/E,YAAY,WAAwB,EAAE,OAAsB,CAAE;QAC5D,IAAI,CAAC,WAAW,GAAG;YACjB,GAAG,WAAW;YACd,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,CAAA,GAAA,0DAAM,CAAA,CAAC,OAAO;YAC5C,MAAM,EAAE,CAAA,GAAA,yBAAkB,CAAA,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;SAC1D,CAAC;QACF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAExD,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,EACrC,IAAI,CAAC,kBAAkB,EAAE,CAAC;KAE7B;IAED,IAAW,eAAe,GAAG;QAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KAC9B;IAED,IAAc,aAAa,GAAqC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,AAAC;QAE/D,IAAI,CAAC,QAAQ,EACX,OAAO,IAAI,CAAC;QAGd,IAAI;YACF,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,AAAC;YAC3C,CAAA,GAAA,aAAM,CAAA,CAAC,IAAI,EAAE,CAAA,GAAA,yCAA4B,CAAA,CAAC,CAAC;YAE3C,OAAO,IAAI,CAAC;SACb,CAAC,OAAO,KAAK,EAAW;YACvB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;SAC9D;KACF;IAED,IAAc,aAAa,CAAC,sBAAwD,EAAE;QACpF,IAAI,CAAC,sBAAsB,EAAE;YAC3B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAEjD,OAAO;SACR;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,AAAC;QACxD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;KACzD;IAED,IAAI,YAAY,GAAG;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;KACrD;IAED,IAAY,YAAY,CAAC,YAA8B,EAAE;QACvD,IAAI,CAAC,YAAY,EAAE;YACjB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAEhD,OAAO;SACR;QAED,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;KAC5D;IAED,IAAI,OAAO,GAAG;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;KACtB;IAED,IAAY,OAAO,CAAC,OAAyB,EAAE;QAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QAExB,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAE3C,OAAO;SACR;QAED,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;KAClD;IAED,sCAAsC;IACtC,MAAa,cAAc,CAAC,QAAiB,EAAmB;QAC9D,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,MAAM,cAAc,GAAG,CAAA,GAAA,yCAAmB,CAAA,CAAC,QAAQ,CAAC,AAAC;QACrD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,AAAC;QAE5D,IAAI,WAAW,IAAI,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAC1D,OAAO,WAAW,CAAC,KAAK,CAAC;QAG3B,8DAA8D;QAC9D,IAAI,WAAW,EACb,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAG7C;;;OAGG,CACH,MAAM,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,cAAc,CAAC,AAAC;QAExE,IAAI,aAAa,EACf,OAAO,aAAa,CAAC;QAGvB;;;;OAIG,CACH,MAAM,OAAO,GAAG,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,AAAC;QAC5D,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAE3D,MAAM,KAAK,GAAG,MAAM,OAAO,AAAC;QAC5B,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAErD,OAAO,KAAK,CAAC;KACd;IAED,AAAO,gBAAgB,GAAkB;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,OAAO,CAAA,GAAA,oBAAa,CAAA,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KACpC;IAED,MAAa,MAAM,CAAC,WAAmB,EAAE;QACvC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,UAAE,MAAM,CAAA,aAAE,SAAS,CAAA,UAAE,MAAM,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QACxE,MAAM,yBAAE,qBAAqB,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,AAAC;QACzD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,YAAY,CAAC,AAAC;QAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,AAAC;QAE3C,MAAM,SAAS,GAAG,CAAA,GAAA,wBAAiB,CAAA,CAAC;mCAClC,qBAAqB;sBACrB,QAAQ;yBACR,WAAW;2BACX,aAAa;mBACb,KAAK;oBACL,MAAM;uBACN,SAAS;oBACT,MAAM;SACP,CAAC,AAAC;QAEH,IAAI,CAAC,aAAa,GAAG;yBAAE,WAAW;0BAAE,YAAY;mBAAE,KAAK;SAAE,CAAC;QAC1D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;KAClC;IAED,AAAO,kBAAkB,CAAC,GAAW,EAAW;QAC9C,MAAM,iBAAE,aAAa,CAAA,EAAE,GAAG,IAAI,AAAC;QAE/B,IAAI,CAAC,aAAa,EAChB,OAAO,KAAK,CAAC;QAEf,MAAM,eAAE,WAAW,CAAA,EAAE,GAAG,aAAa,AAAC;QACtC,MAAM,UAAE,MAAM,CAAA,YAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,AAAC;QAE1C,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,KAAK,WAAW,CAAC;KAC/C;IAED,MAAa,oBAAoB,CAAC,WAAmB,EAAE;QACrD,MAAM,iBAAE,aAAa,CAAA,eAAE,WAAW,CAAA,WAAE,OAAO,CAAA,EAAE,GAAG,IAAI,AAAC;QACrD,MAAM,aAAE,SAAS,CAAA,EAAE,GAAG,OAAO,AAAC;QAE9B,IAAI,CAAC,aAAa,EAChB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,2BAA2B,CAAC,CAAC;QAG1D,MAAM,eAAE,WAAW,CAAA,SAAE,KAAK,CAAA,gBAAE,YAAY,CAAA,EAAE,GAAG,aAAa,AAAC;QAC3D,MAAM,IAAI,GAAG,CAAA,GAAA,wCAAiC,CAAA,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,AAAC;QAEhF,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,EAAE,GAAG,WAAW,AAAC;QACxC,MAAM,iBAAE,aAAa,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QACrD,MAAM,iBAAiB,GAAG,MAAM,CAAA,GAAA,oCAA6B,CAAA,CAC3D;sBACE,QAAQ;2BACR,aAAa;yBACb,WAAW;0BACX,YAAY;kBACZ,IAAI;SACL,EACD,SAAS,CACV,AAAC;QAEF,MAAM,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;KAC3B;IAED,MAAa,OAAO,CAAC,qBAA8B,EAAE;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QAC7C,MAAM,sBAAE,kBAAkB,CAAA,sBAAE,kBAAkB,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAE9E,IAAI,IAAI,CAAC,YAAY,EACnB,IAAI;YACF,MAAM,CAAA,GAAA,aAAM,CAAA,CAAC,kBAAkB,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SACvF,CAAC,OAAM;QACN,yGAAyG;SAC1G;QAGH,MAAM,GAAG,GAAG,CAAA,GAAA,yBAAkB,CAAA,CAAC;gCAC7B,kBAAkB;mCAClB,qBAAqB;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,AAAC;QAEH,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;KAC5B;IAED,MAAc,4BAA4B,CAAC,QAAiB,EAAmB;QAC7E,IAAI,CAAC,IAAI,CAAC,YAAY,EACpB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,IAAI;YACF,MAAM,cAAc,GAAG,CAAA,GAAA,yCAAmB,CAAA,CAAC,QAAQ,CAAC,AAAC;YACrD,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;YAC7C,MAAM,iBAAE,aAAa,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;YACrD,MAAM,eAAE,WAAW,CAAA,gBAAE,YAAY,CAAA,WAAE,OAAO,CAAA,SAAE,KAAK,CAAA,aAAE,SAAS,CAAA,EAAE,GAC5D,MAAM,CAAA,GAAA,+BAAwB,CAAA,CAC5B;0BACE,QAAQ;+BACR,aAAa;gBACb,YAAY,EAAE,IAAI,CAAC,YAAY;0BAC/B,QAAQ;gBACR,MAAM,EAAE,QAAQ,GAAG;oBAAC,gBAAgB;iBAAC,GAAG,SAAS;aAClD,EACD,IAAI,CAAC,OAAO,CAAC,SAAS,CACvB,AAAC;YAEJ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE;gBACtC,KAAK,EAAE,WAAW;uBAClB,KAAK;gBACL,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS;aACrD,CAAC,CAAC;YACH,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAE1B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;YAEjC,IAAI,OAAO,EAAE;gBACX,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;aACxB;YAED,OAAO,WAAW,CAAC;SACpB,CAAC,OAAO,KAAK,EAAW;YACvB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;SAC/E;KACF;IAED,MAAc,cAAc,GAAG;QAC7B,MAAM,YAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QACtC,MAAM,iBAAiB,GAAG,CAAA,GAAA,yCAAoB,CAAA,CAAC,QAAQ,CAAC,AAAC;QAEzD,OAAO,CAAA,GAAA,sBAAe,CAAA,CAAC,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;KACnE;IAED,MAAc,mBAAmB,GAAG;QAClC,MAAM,WAAE,OAAO,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAE/C,OAAO,CAAA,GAAA,yBAAkB,CAAA,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;KAC7C;IAED,MAAc,aAAa,CAAC,OAAe,EAAE;QAC3C,MAAM,SAAE,KAAK,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QACnC,MAAM,UAAE,MAAM,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAC9C,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,AAAC;QAExD,IAAI;YACF,MAAM,CAAA,GAAA,oBAAa,CAAA,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;SAC9D,CAAC,OAAO,KAAK,EAAW;YACvB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;SACvD;KACF;IAED,AAAQ,aAAa,CAAC,gBACpB,YAAY,CAAA,WACZ,OAAO,CAAA,SACP,KAAK,CAAA,eACL,WAAW,CAAA,aACX,SAAS,CAAA,EACS,EAAE;QACpB,IAAI,CAAC,YAAY,GAAG,YAAY,IAAI,IAAI,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,8EAA8E;QAC9E,MAAM,cAAc,GAAG,CAAA,GAAA,yCAAmB,CAAA,EAAE,AAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,AAAC;QAChD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE;YAAE,KAAK,EAAE,WAAW;mBAAE,KAAK;uBAAE,SAAS;SAAE,CAAC,CAAC;QAClF,IAAI,CAAC,kBAAkB,EAAE,CAAC;KAC3B;IAED,AAAQ,kBAAkB,GAAG;QAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,EACtC,OAAO;QAGT,MAAM,IAAI,GAAgC,EAAE,AAAC;QAE7C,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAC5D,sDAAsD;QACtD,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;QAG1B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;KACnE;IAED,AAAQ,kBAAkB,GAAG;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,AAAC;QAExD,IAAI,CAAC,GAAG,EACN,OAAO;QAGT,IAAI;YACF,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,AAAC;YACtC,CAAA,GAAA,aAAM,CAAA,CAAC,IAAI,EAAE,CAAA,GAAA,yCAAyB,CAAA,CAAC,CAAC;YACxC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;YAE5B,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CACnD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;SAE7C,CAAC,OAAM,EAAE;KACX;CACF","sources":["packages/client/src/index.ts","packages/client/src/errors.ts","packages/client/src/types/index.ts","packages/client/src/utils/index.ts","packages/client/src/utils/requester.ts"],"sourcesContent":["import {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert } from 'superstruct';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n LogtoAccessTokenMapSchema,\n LogtoConfig,\n LogtoSignInSessionItem,\n LogtoSignInSessionItemSchema,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';\nexport * from './errors';\nexport type { Storage, StorageKey, ClientAdapter } from './adapter';\nexport { createRequester } from './utils';\nexport * from './types';\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly adapter: ClientAdapter;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n this._idToken = this.adapter.storage.getItem('idToken');\n\n if (this.logtoConfig.persistAccessToken) {\n this.loadAccessTokenMap();\n }\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n get refreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n if (!idToken) {\n this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n this.adapter.storage.setItem('idToken', idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = this.adapter.generateCodeVerifier();\n const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);\n const state = this.adapter.generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, adapter } = this;\n const { requester } = adapter;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.adapter.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.adapter.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n this.saveAccessTokenMap();\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n this.saveAccessTokenMap();\n }\n\n private saveAccessTokenMap() {\n if (!this.logtoConfig.persistAccessToken) {\n return;\n }\n\n const data: Record<string, AccessToken> = {};\n\n for (const [key, accessToken] of this.accessTokenMap.entries()) {\n // eslint-disable-next-line @silverhand/fp/no-mutation\n data[key] = accessToken;\n }\n\n this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private loadAccessTokenMap() {\n const raw = this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n assert(json, LogtoAccessTokenMapSchema);\n this.accessTokenMap.clear();\n\n for (const [key, accessToken] of Object.entries(json)) {\n this.accessTokenMap.set(key, accessToken);\n }\n } catch {}\n }\n}\n","import { NormalizeKeyPaths } from '@silverhand/essentials';\nimport get from 'lodash.get';\n\nconst logtoClientErrorCodes = Object.freeze({\n sign_in_session: {\n invalid: 'Invalid sign-in session.',\n not_found: 'Sign-in session not found.',\n },\n not_authenticated: 'Not authenticated.',\n get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',\n invalid_id_token: 'Invalid id token.',\n});\n\nexport type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;\n\nconst getMessageByErrorCode = (errorCode: LogtoClientErrorCode): string => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const message = get(logtoClientErrorCodes, errorCode);\n\n if (typeof message === 'string') {\n return message;\n }\n\n return errorCode;\n};\n\nexport class LogtoClientError extends Error {\n code: LogtoClientErrorCode;\n data: unknown;\n\n constructor(code: LogtoClientErrorCode, data?: unknown) {\n super(getMessageByErrorCode(code));\n this.code = code;\n this.data = data;\n }\n}\n","import { Prompt } from '@logto/js';\nimport { Infer, number, record, string, type } from 'superstruct';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n persistAccessToken?: boolean;\n};\n\nexport const AccessTokenSchema = type({\n token: string(),\n scope: string(),\n expiresAt: number(),\n});\n\nexport type AccessToken = Infer<typeof AccessTokenSchema>;\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport const LogtoAccessTokenMapSchema = record(string(), AccessTokenSchema);\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n","import { discoveryPath } from '@logto/js';\n\nexport * from './requester';\n\nexport const buildAccessTokenKey = (resource = '', scopes: string[] = []): string =>\n `${scopes.slice().sort().join(' ')}@${resource}`;\n\nexport const getDiscoveryEndpoint = (endpoint: string): string =>\n new URL(discoveryPath, endpoint).toString();\n","import { LogtoRequestError, LogtoRequestErrorBody, Requester } from '@logto/js';\n\nexport const createRequester = (fetchFunction: typeof fetch): Requester => {\n return async <T>(...args: Parameters<typeof fetch>): Promise<T> => {\n const response = await fetchFunction(...args);\n\n if (!response.ok) {\n // Expected request error from server\n const { code, message } = await response.json<LogtoRequestErrorBody>();\n throw new LogtoRequestError(code, message);\n }\n\n return response.json<T>();\n };\n};\n"],"names":[],"version":3,"file":"module.js.map"}
1
+ {"mappings":"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","sources":["packages/client/src/index.ts","packages/client/src/errors.ts","packages/client/src/types/index.ts","packages/client/src/utils/index.ts","packages/client/src/utils/requester.ts"],"sourcesContent":["import {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert } from 'superstruct';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n LogtoAccessTokenMapSchema,\n LogtoConfig,\n LogtoSignInSessionItem,\n LogtoSignInSessionItemSchema,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';\nexport * from './errors';\nexport type { Storage, StorageKey, ClientAdapter } from './adapter';\nexport { createRequester } from './utils';\nexport * from './types';\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly adapter: ClientAdapter;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n this._idToken = this.adapter.storage.getItem('idToken');\n\n if (this.logtoConfig.persistAccessToken) {\n this.loadAccessTokenMap();\n }\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n get refreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n if (!idToken) {\n this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n this.adapter.storage.setItem('idToken', idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = this.adapter.generateCodeVerifier();\n const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);\n const state = this.adapter.generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, adapter } = this;\n const { requester } = adapter;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.adapter.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n this.adapter.navigate(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.adapter.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n this.saveAccessTokenMap();\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n this.saveAccessTokenMap();\n }\n\n private saveAccessTokenMap() {\n if (!this.logtoConfig.persistAccessToken) {\n return;\n }\n\n const data: Record<string, AccessToken> = {};\n\n for (const [key, accessToken] of this.accessTokenMap.entries()) {\n // eslint-disable-next-line @silverhand/fp/no-mutation\n data[key] = accessToken;\n }\n\n this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private loadAccessTokenMap() {\n const raw = this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n assert(json, LogtoAccessTokenMapSchema);\n this.accessTokenMap.clear();\n\n for (const [key, accessToken] of Object.entries(json)) {\n this.accessTokenMap.set(key, accessToken);\n }\n } catch {}\n }\n}\n","import { NormalizeKeyPaths } from '@silverhand/essentials';\nimport get from 'lodash.get';\n\nconst logtoClientErrorCodes = Object.freeze({\n sign_in_session: {\n invalid: 'Invalid sign-in session.',\n not_found: 'Sign-in session not found.',\n },\n not_authenticated: 'Not authenticated.',\n get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',\n invalid_id_token: 'Invalid id token.',\n});\n\nexport type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;\n\nconst getMessageByErrorCode = (errorCode: LogtoClientErrorCode): string => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const message = get(logtoClientErrorCodes, errorCode);\n\n if (typeof message === 'string') {\n return message;\n }\n\n return errorCode;\n};\n\nexport class LogtoClientError extends Error {\n code: LogtoClientErrorCode;\n data: unknown;\n\n constructor(code: LogtoClientErrorCode, data?: unknown) {\n super(getMessageByErrorCode(code));\n this.code = code;\n this.data = data;\n }\n}\n","import { Prompt } from '@logto/js';\nimport { Infer, number, record, string, type } from 'superstruct';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n appSecret?: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n persistAccessToken?: boolean;\n};\n\nexport const AccessTokenSchema = type({\n token: string(),\n scope: string(),\n expiresAt: number(),\n});\n\nexport type AccessToken = Infer<typeof AccessTokenSchema>;\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport const LogtoAccessTokenMapSchema = record(string(), AccessTokenSchema);\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n","import { discoveryPath } from '@logto/js';\n\nexport * from './requester';\n\nexport const buildAccessTokenKey = (resource = '', scopes: string[] = []): string =>\n `${scopes.slice().sort().join(' ')}@${resource}`;\n\nexport const getDiscoveryEndpoint = (endpoint: string): string =>\n new URL(discoveryPath, endpoint).toString();\n","import { LogtoError, LogtoRequestError, logtoRequestErrorSchema, Requester } from '@logto/js';\n\nexport const createRequester = (fetchFunction: typeof fetch): Requester => {\n return async <T>(...args: Parameters<typeof fetch>): Promise<T> => {\n const response = await fetchFunction(...args);\n\n if (!response.ok) {\n const responseJson = await response.json();\n\n if (!logtoRequestErrorSchema.is(responseJson)) {\n throw new LogtoError('unexpected_response_error', responseJson);\n }\n\n // Expected request error from server\n const { code, message } = responseJson;\n throw new LogtoRequestError(code, message);\n }\n\n return response.json();\n };\n};\n"],"names":[],"version":3,"file":"module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logto/client",
3
- "version": "1.0.0-beta.0",
3
+ "version": "1.0.0-beta.2",
4
4
  "source": "./src/index.ts",
5
5
  "main": "./lib/index.js",
6
6
  "exports": {
@@ -29,7 +29,7 @@
29
29
  "prepack": "pnpm test"
30
30
  },
31
31
  "dependencies": {
32
- "@logto/js": "^1.0.0-beta.0",
32
+ "@logto/js": "^1.0.0-beta.2",
33
33
  "@silverhand/essentials": "^1.1.6",
34
34
  "camelcase-keys": "^7.0.1",
35
35
  "jose": "^4.3.8",
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "f0f78e6f0b97174de98588b35d1d12c8396206ba"
70
+ "gitHead": "212891497b04e3a5fd6b24bbbeec227dfec8ae53"
71
71
  }