@logto/client 1.0.0-beta.6 → 1.0.0-beta.8
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 +8 -26
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +29 -28
- package/lib/index.js.map +1 -1
- package/lib/module.js +29 -30
- package/lib/module.js.map +1 -1
- package/package.json +5 -5
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Requester, Prompt, IdTokenClaims, UserInfoResponse } from "@logto/js";
|
|
2
2
|
import { Nullable, NormalizeKeyPaths } from "@silverhand/essentials";
|
|
3
|
-
import { Infer } from "superstruct";
|
|
4
3
|
export type StorageKey = 'idToken' | 'refreshToken' | 'accessToken' | 'signInSession';
|
|
5
4
|
export type Storage = {
|
|
6
5
|
getItem(key: StorageKey): Promise<Nullable<string>>;
|
|
@@ -39,46 +38,29 @@ export type LogtoConfig = {
|
|
|
39
38
|
scopes?: string[];
|
|
40
39
|
resources?: string[];
|
|
41
40
|
prompt?: Prompt;
|
|
42
|
-
persistAccessToken?: boolean;
|
|
43
41
|
};
|
|
44
|
-
export
|
|
42
|
+
export type AccessToken = {
|
|
45
43
|
token: string;
|
|
46
44
|
scope: string;
|
|
47
45
|
expiresAt: number;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}>;
|
|
53
|
-
export type AccessToken = Infer<typeof AccessTokenSchema>;
|
|
54
|
-
export const LogtoSignInSessionItemSchema: import("superstruct").Struct<{
|
|
46
|
+
};
|
|
47
|
+
export const isLogtoSignInSessionItem: (data: unknown) => data is LogtoSignInSessionItem;
|
|
48
|
+
export const isLogtoAccessTokenMap: (data: unknown) => data is Record<string, AccessToken>;
|
|
49
|
+
export type LogtoSignInSessionItem = {
|
|
55
50
|
redirectUri: string;
|
|
56
51
|
codeVerifier: string;
|
|
57
52
|
state: string;
|
|
58
|
-
}
|
|
59
|
-
redirectUri: import("superstruct").Struct<string, null>;
|
|
60
|
-
codeVerifier: import("superstruct").Struct<string, null>;
|
|
61
|
-
state: import("superstruct").Struct<string, null>;
|
|
62
|
-
}>;
|
|
63
|
-
export const LogtoAccessTokenMapSchema: import("superstruct").Struct<Record<string, {
|
|
64
|
-
token: string;
|
|
65
|
-
scope: string;
|
|
66
|
-
expiresAt: number;
|
|
67
|
-
}>, null>;
|
|
68
|
-
export type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;
|
|
53
|
+
};
|
|
69
54
|
export const createRequester: (fetchFunction: typeof fetch) => Requester;
|
|
70
55
|
export type { IdTokenClaims, LogtoErrorCode, UserInfoResponse } from '@logto/js';
|
|
71
56
|
export { LogtoError, OidcError, Prompt, LogtoRequestError } from '@logto/js';
|
|
57
|
+
export { ReservedScope, UserScope } from '@logto/core-kit';
|
|
72
58
|
export default class LogtoClient {
|
|
73
59
|
protected readonly logtoConfig: LogtoConfig;
|
|
74
60
|
protected readonly getOidcConfig: () => Promise<import("@silverhand/essentials").KeysToCamelCase<import("@logto/js").OidcConfigSnakeCaseResponse>>;
|
|
75
61
|
protected readonly getJwtVerifyGetKey: () => Promise<import("jose/dist/types/types").GetKeyFunction<import("jose").JWSHeaderParameters, import("jose").FlattenedJWSInput>>;
|
|
76
62
|
protected readonly adapter: ClientAdapter;
|
|
77
|
-
protected readonly accessTokenMap: Map<string,
|
|
78
|
-
token: string;
|
|
79
|
-
scope: string;
|
|
80
|
-
expiresAt: number;
|
|
81
|
-
}>;
|
|
63
|
+
protected readonly accessTokenMap: Map<string, AccessToken>;
|
|
82
64
|
constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter);
|
|
83
65
|
isAuthenticated(): Promise<boolean>;
|
|
84
66
|
getRefreshToken(): Promise<Nullable<string>>;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -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,"/* eslint-disable max-lines */\nimport {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n fetchUserInfo,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n UserInfoResponse,\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, UserInfoResponse } 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 protected readonly adapter: ClientAdapter;\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<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\n if (this.logtoConfig.persistAccessToken) {\n void this.loadAccessTokenMap();\n }\n }\n\n async isAuthenticated() {\n return Boolean(await this.getIdToken());\n }\n\n async getRefreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n async getIdToken() {\n return this.adapter.storage.getItem('idToken');\n }\n\n // eslint-disable-next-line complexity\n async getAccessToken(resource?: string): Promise<string> {\n if (!(await this.getIdToken())) {\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 async getIdTokenClaims(): Promise<IdTokenClaims> {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(idToken);\n }\n\n async fetchUserInfo(): Promise<UserInfoResponse> {\n const { userinfoEndpoint } = await this.getOidcConfig();\n const accessToken = await this.getAccessToken();\n\n if (!accessToken) {\n throw new LogtoClientError('fetch_user_info_failed');\n }\n\n return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);\n }\n\n 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 await this.setSignInSession({ redirectUri, codeVerifier, state });\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(signInUri);\n }\n\n async isSignInRedirected(url: string): Promise<boolean> {\n const signInSession = await this.getSignInSession();\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 async handleSignInCallback(callbackUri: string) {\n const { logtoConfig, adapter } = this;\n const { requester } = adapter;\n const signInSession = await this.getSignInSession();\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 await this.saveCodeToken(codeTokenResponse);\n await this.setSignInSession(null);\n }\n\n async signOut(postLogoutRedirectUri?: string) {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n const refreshToken = await this.getRefreshToken();\n\n if (refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, 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,\n });\n\n this.accessTokenMap.clear();\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(url);\n }\n\n protected async getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>> {\n const jsonItem = await 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 async setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n await this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n await this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n private async setIdToken(idToken: Nullable<string>) {\n if (!idToken) {\n await this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('idToken', idToken);\n }\n\n private async setRefreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n await this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n const currentRefreshToken = await this.getRefreshToken();\n\n if (!currentRefreshToken) {\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: currentRefreshToken,\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\n await this.saveAccessTokenMap();\n await this.setRefreshToken(refreshToken);\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n await this.setIdToken(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 async saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n await this.setRefreshToken(refreshToken ?? null);\n await this.setIdToken(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 await this.saveAccessTokenMap();\n }\n\n private async 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 await this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private async loadAccessTokenMap() {\n const raw = await 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/* eslint-enable max-lines */\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,"/* eslint-disable max-lines */\nimport { ReservedScope } from '@logto/core-kit';\nimport {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n fetchUserInfo,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n UserInfoResponse,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withDefaultScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n isLogtoAccessTokenMap,\n isLogtoSignInSessionItem,\n LogtoConfig,\n LogtoSignInSessionItem,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode, UserInfoResponse } 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';\nexport { ReservedScope, UserScope } from '@logto/core-kit';\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 protected readonly adapter: ClientAdapter;\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withDefaultScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n\n void this.loadAccessTokenMap();\n }\n\n async isAuthenticated() {\n return Boolean(await this.getIdToken());\n }\n\n async getRefreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n async getIdToken() {\n return this.adapter.storage.getItem('idToken');\n }\n\n // eslint-disable-next-line complexity\n async getAccessToken(resource?: string): Promise<string> {\n if (!(await this.getIdToken())) {\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 async getIdTokenClaims(): Promise<IdTokenClaims> {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(idToken);\n }\n\n async fetchUserInfo(): Promise<UserInfoResponse> {\n const { userinfoEndpoint } = await this.getOidcConfig();\n const accessToken = await this.getAccessToken();\n\n if (!accessToken) {\n throw new LogtoClientError('fetch_user_info_failed');\n }\n\n return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);\n }\n\n 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 await this.setSignInSession({ redirectUri, codeVerifier, state });\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(signInUri);\n }\n\n async isSignInRedirected(url: string): Promise<boolean> {\n const signInSession = await this.getSignInSession();\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 async handleSignInCallback(callbackUri: string) {\n const { logtoConfig, adapter } = this;\n const { requester } = adapter;\n const signInSession = await this.getSignInSession();\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 await this.saveCodeToken(codeTokenResponse);\n await this.setSignInSession(null);\n }\n\n async signOut(postLogoutRedirectUri?: string) {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n const refreshToken = await this.getRefreshToken();\n\n if (refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, 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,\n });\n\n this.accessTokenMap.clear();\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(url);\n }\n\n protected async getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>> {\n const jsonItem = await this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n const item: unknown = JSON.parse(jsonItem);\n\n if (!isLogtoSignInSessionItem(item)) {\n throw new LogtoClientError('sign_in_session.invalid');\n }\n\n return item;\n }\n\n protected async setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n await this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n await this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n private async setIdToken(idToken: Nullable<string>) {\n if (!idToken) {\n await this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('idToken', idToken);\n }\n\n private async setRefreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n await this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n const currentRefreshToken = await this.getRefreshToken();\n\n if (!currentRefreshToken) {\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: currentRefreshToken,\n resource,\n scopes: resource ? [ReservedScope.OfflineAccess] : 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\n await this.saveAccessTokenMap();\n await this.setRefreshToken(refreshToken);\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n await this.setIdToken(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 async saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n await this.setRefreshToken(refreshToken ?? null);\n await this.setIdToken(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 await this.saveAccessTokenMap();\n }\n\n private async saveAccessTokenMap() {\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 await this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private async loadAccessTokenMap() {\n const raw = await this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n\n if (!isLogtoAccessTokenMap(json)) {\n return;\n }\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/* eslint-enable max-lines */\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
var $4R6L3$logtocorekit = require("@logto/core-kit");
|
|
1
2
|
var $4R6L3$logtojs = require("@logto/js");
|
|
2
3
|
var $4R6L3$jose = require("jose");
|
|
3
4
|
var $4R6L3$lodashonce = require("lodash.once");
|
|
4
|
-
var $4R6L3$superstruct = require("superstruct");
|
|
5
5
|
var $4R6L3$lodashget = require("lodash.get");
|
|
6
6
|
|
|
7
7
|
function $parcel$interopDefault(a) {
|
|
@@ -38,6 +38,8 @@ $parcel$export(module.exports, "OidcError", () => $f73788ae50447ce9$re_export$Oi
|
|
|
38
38
|
$parcel$export(module.exports, "Prompt", () => $4R6L3$logtojs.Prompt);
|
|
39
39
|
$parcel$export(module.exports, "LogtoRequestError", () => $f73788ae50447ce9$re_export$LogtoRequestError);
|
|
40
40
|
$parcel$export(module.exports, "createRequester", () => $b455f57f80fbf6bf$export$8d54726fdbf08e0a);
|
|
41
|
+
$parcel$export(module.exports, "ReservedScope", () => $4R6L3$logtocorekit.ReservedScope);
|
|
42
|
+
$parcel$export(module.exports, "UserScope", () => $f73788ae50447ce9$re_export$UserScope);
|
|
41
43
|
|
|
42
44
|
|
|
43
45
|
|
|
@@ -73,21 +75,24 @@ class $9166104b36889c59$export$877962ca249b8fc8 extends Error {
|
|
|
73
75
|
|
|
74
76
|
var $6d3989f7f53311af$exports = {};
|
|
75
77
|
|
|
76
|
-
$parcel$export($6d3989f7f53311af$exports, "
|
|
77
|
-
$parcel$export($6d3989f7f53311af$exports, "
|
|
78
|
-
$parcel$export($6d3989f7f53311af$exports, "LogtoAccessTokenMapSchema", () => $6d3989f7f53311af$export$4ae7b9c313038df5);
|
|
78
|
+
$parcel$export($6d3989f7f53311af$exports, "isLogtoSignInSessionItem", () => $6d3989f7f53311af$export$5d8adf6e063019de);
|
|
79
|
+
$parcel$export($6d3989f7f53311af$exports, "isLogtoAccessTokenMap", () => $6d3989f7f53311af$export$c12fab42a9a3e2a6);
|
|
79
80
|
|
|
80
|
-
const $6d3989f7f53311af$export$
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
const $6d3989f7f53311af$export$5d8adf6e063019de = (data)=>{
|
|
82
|
+
if (!(0, $4R6L3$logtojs.isArbitraryObject)(data)) return false;
|
|
83
|
+
return [
|
|
84
|
+
"redirectUri",
|
|
85
|
+
"codeVerifier",
|
|
86
|
+
"state"
|
|
87
|
+
].every((key)=>typeof data[key] === "string");
|
|
88
|
+
};
|
|
89
|
+
const $6d3989f7f53311af$export$c12fab42a9a3e2a6 = (data)=>{
|
|
90
|
+
if (!(0, $4R6L3$logtojs.isArbitraryObject)(data)) return false;
|
|
91
|
+
return Object.values(data).every((value)=>{
|
|
92
|
+
if (!(0, $4R6L3$logtojs.isArbitraryObject)(value)) return false;
|
|
93
|
+
return typeof value.token === "string" && typeof value.scope === "string" && typeof value.expiresAt === "number";
|
|
94
|
+
});
|
|
95
|
+
};
|
|
91
96
|
|
|
92
97
|
|
|
93
98
|
|
|
@@ -97,7 +102,7 @@ const $b455f57f80fbf6bf$export$8d54726fdbf08e0a = (fetchFunction)=>{
|
|
|
97
102
|
const response = await fetchFunction(...args);
|
|
98
103
|
if (!response.ok) {
|
|
99
104
|
const responseJson = await response.json();
|
|
100
|
-
if (!(0, $4R6L3$logtojs.
|
|
105
|
+
if (!(0, $4R6L3$logtojs.isLogtoRequestError)(responseJson)) throw new (0, $4R6L3$logtojs.LogtoError)("unexpected_response_error", responseJson);
|
|
101
106
|
// Expected request error from server
|
|
102
107
|
const { code: code , message: message } = responseJson;
|
|
103
108
|
throw new (0, $4R6L3$logtojs.LogtoRequestError)(code, message);
|
|
@@ -115,6 +120,7 @@ const $e2aabdbdb3cc09f0$export$5d9c34f69c80822b = (endpoint)=>new URL((0, $4R6L3
|
|
|
115
120
|
|
|
116
121
|
|
|
117
122
|
|
|
123
|
+
|
|
118
124
|
class $f73788ae50447ce9$export$2e2bcd8739ae039 {
|
|
119
125
|
getOidcConfig = (0, ($parcel$interopDefault($4R6L3$lodashonce)))(this._getOidcConfig);
|
|
120
126
|
getJwtVerifyGetKey = (0, ($parcel$interopDefault($4R6L3$lodashonce)))(this._getJwtVerifyGetKey);
|
|
@@ -124,10 +130,10 @@ class $f73788ae50447ce9$export$2e2bcd8739ae039 {
|
|
|
124
130
|
this.logtoConfig = {
|
|
125
131
|
...logtoConfig,
|
|
126
132
|
prompt: logtoConfig.prompt ?? (0, $4R6L3$logtojs.Prompt).Consent,
|
|
127
|
-
scopes: (0, $4R6L3$logtojs.
|
|
133
|
+
scopes: (0, $4R6L3$logtojs.withDefaultScopes)(logtoConfig.scopes).split(" ")
|
|
128
134
|
};
|
|
129
135
|
this.adapter = adapter;
|
|
130
|
-
|
|
136
|
+
this.loadAccessTokenMap();
|
|
131
137
|
}
|
|
132
138
|
async isAuthenticated() {
|
|
133
139
|
return Boolean(await this.getIdToken());
|
|
@@ -248,13 +254,9 @@ class $f73788ae50447ce9$export$2e2bcd8739ae039 {
|
|
|
248
254
|
async getSignInSession() {
|
|
249
255
|
const jsonItem = await this.adapter.storage.getItem("signInSession");
|
|
250
256
|
if (!jsonItem) return null;
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return item;
|
|
255
|
-
} catch (error) {
|
|
256
|
-
throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("sign_in_session.invalid", error);
|
|
257
|
-
}
|
|
257
|
+
const item = JSON.parse(jsonItem);
|
|
258
|
+
if (!(0, $6d3989f7f53311af$export$5d8adf6e063019de)(item)) throw new (0, $9166104b36889c59$export$877962ca249b8fc8)("sign_in_session.invalid");
|
|
259
|
+
return item;
|
|
258
260
|
}
|
|
259
261
|
async setSignInSession(logtoSignInSessionItem) {
|
|
260
262
|
if (!logtoSignInSessionItem) {
|
|
@@ -291,7 +293,7 @@ class $f73788ae50447ce9$export$2e2bcd8739ae039 {
|
|
|
291
293
|
refreshToken: currentRefreshToken,
|
|
292
294
|
resource: resource,
|
|
293
295
|
scopes: resource ? [
|
|
294
|
-
|
|
296
|
+
(0, $4R6L3$logtocorekit.ReservedScope).OfflineAccess
|
|
295
297
|
] : undefined
|
|
296
298
|
}, this.adapter.requester);
|
|
297
299
|
this.accessTokenMap.set(accessTokenKey, {
|
|
@@ -343,7 +345,6 @@ class $f73788ae50447ce9$export$2e2bcd8739ae039 {
|
|
|
343
345
|
await this.saveAccessTokenMap();
|
|
344
346
|
}
|
|
345
347
|
async saveAccessTokenMap() {
|
|
346
|
-
if (!this.logtoConfig.persistAccessToken) return;
|
|
347
348
|
const data = {};
|
|
348
349
|
for (const [key, accessToken] of this.accessTokenMap.entries())// eslint-disable-next-line @silverhand/fp/no-mutation
|
|
349
350
|
data[key] = accessToken;
|
|
@@ -354,7 +355,7 @@ class $f73788ae50447ce9$export$2e2bcd8739ae039 {
|
|
|
354
355
|
if (!raw) return;
|
|
355
356
|
try {
|
|
356
357
|
const json = JSON.parse(raw);
|
|
357
|
-
|
|
358
|
+
if (!(0, $6d3989f7f53311af$export$c12fab42a9a3e2a6)(json)) return;
|
|
358
359
|
this.accessTokenMap.clear();
|
|
359
360
|
for (const [key, accessToken] of Object.entries(json))this.accessTokenMap.set(key, accessToken);
|
|
360
361
|
} catch {}
|
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":["/* eslint-disable max-lines */\nimport {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n fetchUserInfo,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n UserInfoResponse,\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, UserInfoResponse } 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 protected readonly adapter: ClientAdapter;\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<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\n if (this.logtoConfig.persistAccessToken) {\n void this.loadAccessTokenMap();\n }\n }\n\n async isAuthenticated() {\n return Boolean(await this.getIdToken());\n }\n\n async getRefreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n async getIdToken() {\n return this.adapter.storage.getItem('idToken');\n }\n\n // eslint-disable-next-line complexity\n async getAccessToken(resource?: string): Promise<string> {\n if (!(await this.getIdToken())) {\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 async getIdTokenClaims(): Promise<IdTokenClaims> {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(idToken);\n }\n\n async fetchUserInfo(): Promise<UserInfoResponse> {\n const { userinfoEndpoint } = await this.getOidcConfig();\n const accessToken = await this.getAccessToken();\n\n if (!accessToken) {\n throw new LogtoClientError('fetch_user_info_failed');\n }\n\n return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);\n }\n\n 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 await this.setSignInSession({ redirectUri, codeVerifier, state });\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(signInUri);\n }\n\n async isSignInRedirected(url: string): Promise<boolean> {\n const signInSession = await this.getSignInSession();\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 async handleSignInCallback(callbackUri: string) {\n const { logtoConfig, adapter } = this;\n const { requester } = adapter;\n const signInSession = await this.getSignInSession();\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 await this.saveCodeToken(codeTokenResponse);\n await this.setSignInSession(null);\n }\n\n async signOut(postLogoutRedirectUri?: string) {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n const refreshToken = await this.getRefreshToken();\n\n if (refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, 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,\n });\n\n this.accessTokenMap.clear();\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(url);\n }\n\n protected async getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>> {\n const jsonItem = await 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 async setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n await this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n await this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n private async setIdToken(idToken: Nullable<string>) {\n if (!idToken) {\n await this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('idToken', idToken);\n }\n\n private async setRefreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n await this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n const currentRefreshToken = await this.getRefreshToken();\n\n if (!currentRefreshToken) {\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: currentRefreshToken,\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\n await this.saveAccessTokenMap();\n await this.setRefreshToken(refreshToken);\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n await this.setIdToken(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 async saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n await this.setRefreshToken(refreshToken ?? null);\n await this.setIdToken(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 await this.saveAccessTokenMap();\n }\n\n private async 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 await this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private async loadAccessTokenMap() {\n const raw = await 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/* eslint-enable max-lines */\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 fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',\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"}
|
|
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":["/* eslint-disable max-lines */\nimport { ReservedScope } from '@logto/core-kit';\nimport {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n fetchUserInfo,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n UserInfoResponse,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withDefaultScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n isLogtoAccessTokenMap,\n isLogtoSignInSessionItem,\n LogtoConfig,\n LogtoSignInSessionItem,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode, UserInfoResponse } 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';\nexport { ReservedScope, UserScope } from '@logto/core-kit';\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 protected readonly adapter: ClientAdapter;\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withDefaultScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n\n void this.loadAccessTokenMap();\n }\n\n async isAuthenticated() {\n return Boolean(await this.getIdToken());\n }\n\n async getRefreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n async getIdToken() {\n return this.adapter.storage.getItem('idToken');\n }\n\n // eslint-disable-next-line complexity\n async getAccessToken(resource?: string): Promise<string> {\n if (!(await this.getIdToken())) {\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 async getIdTokenClaims(): Promise<IdTokenClaims> {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(idToken);\n }\n\n async fetchUserInfo(): Promise<UserInfoResponse> {\n const { userinfoEndpoint } = await this.getOidcConfig();\n const accessToken = await this.getAccessToken();\n\n if (!accessToken) {\n throw new LogtoClientError('fetch_user_info_failed');\n }\n\n return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);\n }\n\n 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 await this.setSignInSession({ redirectUri, codeVerifier, state });\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(signInUri);\n }\n\n async isSignInRedirected(url: string): Promise<boolean> {\n const signInSession = await this.getSignInSession();\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 async handleSignInCallback(callbackUri: string) {\n const { logtoConfig, adapter } = this;\n const { requester } = adapter;\n const signInSession = await this.getSignInSession();\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 await this.saveCodeToken(codeTokenResponse);\n await this.setSignInSession(null);\n }\n\n async signOut(postLogoutRedirectUri?: string) {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n const refreshToken = await this.getRefreshToken();\n\n if (refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, 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,\n });\n\n this.accessTokenMap.clear();\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(url);\n }\n\n protected async getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>> {\n const jsonItem = await this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n const item: unknown = JSON.parse(jsonItem);\n\n if (!isLogtoSignInSessionItem(item)) {\n throw new LogtoClientError('sign_in_session.invalid');\n }\n\n return item;\n }\n\n protected async setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n await this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n await this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n private async setIdToken(idToken: Nullable<string>) {\n if (!idToken) {\n await this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('idToken', idToken);\n }\n\n private async setRefreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n await this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n const currentRefreshToken = await this.getRefreshToken();\n\n if (!currentRefreshToken) {\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: currentRefreshToken,\n resource,\n scopes: resource ? [ReservedScope.OfflineAccess] : 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\n await this.saveAccessTokenMap();\n await this.setRefreshToken(refreshToken);\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n await this.setIdToken(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 async saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n await this.setRefreshToken(refreshToken ?? null);\n await this.setIdToken(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 await this.saveAccessTokenMap();\n }\n\n private async saveAccessTokenMap() {\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 await this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private async loadAccessTokenMap() {\n const raw = await this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n\n if (!isLogtoAccessTokenMap(json)) {\n return;\n }\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/* eslint-enable max-lines */\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 fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',\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 { isArbitraryObject, Prompt } from '@logto/js';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n appSecret?: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n};\n\nexport type AccessToken = {\n token: string;\n scope: string;\n expiresAt: number;\n};\n\nexport const isLogtoSignInSessionItem = (data: unknown): data is LogtoSignInSessionItem => {\n if (!isArbitraryObject(data)) {\n return false;\n }\n\n return ['redirectUri', 'codeVerifier', 'state'].every((key) => typeof data[key] === 'string');\n};\n\nexport const isLogtoAccessTokenMap = (data: unknown): data is Record<string, AccessToken> => {\n if (!isArbitraryObject(data)) {\n return false;\n }\n\n return Object.values(data).every((value) => {\n if (!isArbitraryObject(value)) {\n return false;\n }\n\n return (\n typeof value.token === 'string' &&\n typeof value.scope === 'string' &&\n typeof value.expiresAt === 'number'\n );\n });\n};\n\nexport type LogtoSignInSessionItem = {\n redirectUri: string;\n codeVerifier: string;\n state: string;\n};\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, isLogtoRequestError, 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 (!isLogtoRequestError(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,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {ReservedScope as $19775a679e2952df$import$2bf383245f9cd522$1d2e82cebfd4b08, UserScope as $19775a679e2952df$re_export$UserScope} from "@logto/core-kit";
|
|
2
|
+
import {Prompt as $19775a679e2952df$import$5548085c5b0a2ee3$83716a4aa1642908, withDefaultScopes as $kqBTI$withDefaultScopes, decodeIdToken as $kqBTI$decodeIdToken, fetchUserInfo as $kqBTI$fetchUserInfo, 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, isArbitraryObject as $kqBTI$isArbitraryObject, discoveryPath as $kqBTI$discoveryPath, isLogtoRequestError as $kqBTI$isLogtoRequestError} from "@logto/js";
|
|
2
3
|
import {createRemoteJWKSet as $kqBTI$createRemoteJWKSet} from "jose";
|
|
3
4
|
import $kqBTI$lodashonce from "lodash.once";
|
|
4
|
-
import {assert as $kqBTI$assert, type as $kqBTI$type, string as $kqBTI$string, number as $kqBTI$number, record as $kqBTI$record} from "superstruct";
|
|
5
5
|
import $kqBTI$lodashget from "lodash.get";
|
|
6
6
|
|
|
7
7
|
function $parcel$export(e, n, v, s) {
|
|
@@ -42,21 +42,24 @@ class $4ec05cedcef20733$export$877962ca249b8fc8 extends Error {
|
|
|
42
42
|
|
|
43
43
|
var $50f2bb780a45e70c$exports = {};
|
|
44
44
|
|
|
45
|
-
$parcel$export($50f2bb780a45e70c$exports, "
|
|
46
|
-
$parcel$export($50f2bb780a45e70c$exports, "
|
|
47
|
-
$parcel$export($50f2bb780a45e70c$exports, "LogtoAccessTokenMapSchema", () => $50f2bb780a45e70c$export$4ae7b9c313038df5);
|
|
45
|
+
$parcel$export($50f2bb780a45e70c$exports, "isLogtoSignInSessionItem", () => $50f2bb780a45e70c$export$5d8adf6e063019de);
|
|
46
|
+
$parcel$export($50f2bb780a45e70c$exports, "isLogtoAccessTokenMap", () => $50f2bb780a45e70c$export$c12fab42a9a3e2a6);
|
|
48
47
|
|
|
49
|
-
const $50f2bb780a45e70c$export$
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
const $50f2bb780a45e70c$export$5d8adf6e063019de = (data)=>{
|
|
49
|
+
if (!(0, $kqBTI$isArbitraryObject)(data)) return false;
|
|
50
|
+
return [
|
|
51
|
+
"redirectUri",
|
|
52
|
+
"codeVerifier",
|
|
53
|
+
"state"
|
|
54
|
+
].every((key)=>typeof data[key] === "string");
|
|
55
|
+
};
|
|
56
|
+
const $50f2bb780a45e70c$export$c12fab42a9a3e2a6 = (data)=>{
|
|
57
|
+
if (!(0, $kqBTI$isArbitraryObject)(data)) return false;
|
|
58
|
+
return Object.values(data).every((value)=>{
|
|
59
|
+
if (!(0, $kqBTI$isArbitraryObject)(value)) return false;
|
|
60
|
+
return typeof value.token === "string" && typeof value.scope === "string" && typeof value.expiresAt === "number";
|
|
61
|
+
});
|
|
62
|
+
};
|
|
60
63
|
|
|
61
64
|
|
|
62
65
|
|
|
@@ -66,7 +69,7 @@ const $8449a5dbad0d6387$export$8d54726fdbf08e0a = (fetchFunction)=>{
|
|
|
66
69
|
const response = await fetchFunction(...args);
|
|
67
70
|
if (!response.ok) {
|
|
68
71
|
const responseJson = await response.json();
|
|
69
|
-
if (!(0, $kqBTI$
|
|
72
|
+
if (!(0, $kqBTI$isLogtoRequestError)(responseJson)) throw new (0, $19775a679e2952df$re_export$LogtoError)("unexpected_response_error", responseJson);
|
|
70
73
|
// Expected request error from server
|
|
71
74
|
const { code: code , message: message } = responseJson;
|
|
72
75
|
throw new (0, $19775a679e2952df$re_export$LogtoRequestError)(code, message);
|
|
@@ -84,6 +87,7 @@ const $dcfd5d64758ae70b$export$5d9c34f69c80822b = (endpoint)=>new URL((0, $kqBTI
|
|
|
84
87
|
|
|
85
88
|
|
|
86
89
|
|
|
90
|
+
|
|
87
91
|
class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
88
92
|
getOidcConfig = (0, $kqBTI$lodashonce)(this._getOidcConfig);
|
|
89
93
|
getJwtVerifyGetKey = (0, $kqBTI$lodashonce)(this._getJwtVerifyGetKey);
|
|
@@ -93,10 +97,10 @@ class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
|
93
97
|
this.logtoConfig = {
|
|
94
98
|
...logtoConfig,
|
|
95
99
|
prompt: logtoConfig.prompt ?? (0, $19775a679e2952df$import$5548085c5b0a2ee3$83716a4aa1642908).Consent,
|
|
96
|
-
scopes: (0, $kqBTI$
|
|
100
|
+
scopes: (0, $kqBTI$withDefaultScopes)(logtoConfig.scopes).split(" ")
|
|
97
101
|
};
|
|
98
102
|
this.adapter = adapter;
|
|
99
|
-
|
|
103
|
+
this.loadAccessTokenMap();
|
|
100
104
|
}
|
|
101
105
|
async isAuthenticated() {
|
|
102
106
|
return Boolean(await this.getIdToken());
|
|
@@ -217,13 +221,9 @@ class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
|
217
221
|
async getSignInSession() {
|
|
218
222
|
const jsonItem = await this.adapter.storage.getItem("signInSession");
|
|
219
223
|
if (!jsonItem) return null;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return item;
|
|
224
|
-
} catch (error) {
|
|
225
|
-
throw new (0, $4ec05cedcef20733$export$877962ca249b8fc8)("sign_in_session.invalid", error);
|
|
226
|
-
}
|
|
224
|
+
const item = JSON.parse(jsonItem);
|
|
225
|
+
if (!(0, $50f2bb780a45e70c$export$5d8adf6e063019de)(item)) throw new (0, $4ec05cedcef20733$export$877962ca249b8fc8)("sign_in_session.invalid");
|
|
226
|
+
return item;
|
|
227
227
|
}
|
|
228
228
|
async setSignInSession(logtoSignInSessionItem) {
|
|
229
229
|
if (!logtoSignInSessionItem) {
|
|
@@ -260,7 +260,7 @@ class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
|
260
260
|
refreshToken: currentRefreshToken,
|
|
261
261
|
resource: resource,
|
|
262
262
|
scopes: resource ? [
|
|
263
|
-
|
|
263
|
+
(0, $19775a679e2952df$import$2bf383245f9cd522$1d2e82cebfd4b08).OfflineAccess
|
|
264
264
|
] : undefined
|
|
265
265
|
}, this.adapter.requester);
|
|
266
266
|
this.accessTokenMap.set(accessTokenKey, {
|
|
@@ -312,7 +312,6 @@ class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
|
312
312
|
await this.saveAccessTokenMap();
|
|
313
313
|
}
|
|
314
314
|
async saveAccessTokenMap() {
|
|
315
|
-
if (!this.logtoConfig.persistAccessToken) return;
|
|
316
315
|
const data = {};
|
|
317
316
|
for (const [key, accessToken] of this.accessTokenMap.entries())// eslint-disable-next-line @silverhand/fp/no-mutation
|
|
318
317
|
data[key] = accessToken;
|
|
@@ -323,7 +322,7 @@ class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
|
323
322
|
if (!raw) return;
|
|
324
323
|
try {
|
|
325
324
|
const json = JSON.parse(raw);
|
|
326
|
-
|
|
325
|
+
if (!(0, $50f2bb780a45e70c$export$c12fab42a9a3e2a6)(json)) return;
|
|
327
326
|
this.accessTokenMap.clear();
|
|
328
327
|
for (const [key, accessToken] of Object.entries(json))this.accessTokenMap.set(key, accessToken);
|
|
329
328
|
} catch {}
|
|
@@ -331,5 +330,5 @@ class $19775a679e2952df$export$2e2bcd8739ae039 {
|
|
|
331
330
|
} /* eslint-enable max-lines */
|
|
332
331
|
|
|
333
332
|
|
|
334
|
-
export {$19775a679e2952df$export$2e2bcd8739ae039 as default, $19775a679e2952df$re_export$LogtoError as LogtoError, $19775a679e2952df$re_export$OidcError as OidcError, $19775a679e2952df$import$5548085c5b0a2ee3$83716a4aa1642908 as Prompt, $19775a679e2952df$re_export$LogtoRequestError as LogtoRequestError, $8449a5dbad0d6387$export$8d54726fdbf08e0a as createRequester, $
|
|
333
|
+
export {$19775a679e2952df$export$2e2bcd8739ae039 as default, $19775a679e2952df$re_export$LogtoError as LogtoError, $19775a679e2952df$re_export$OidcError as OidcError, $19775a679e2952df$import$5548085c5b0a2ee3$83716a4aa1642908 as Prompt, $19775a679e2952df$re_export$LogtoRequestError as LogtoRequestError, $8449a5dbad0d6387$export$8d54726fdbf08e0a as createRequester, $19775a679e2952df$import$2bf383245f9cd522$1d2e82cebfd4b08 as ReservedScope, $19775a679e2952df$re_export$UserScope as UserScope, $4ec05cedcef20733$export$877962ca249b8fc8 as LogtoClientError, $50f2bb780a45e70c$export$5d8adf6e063019de as isLogtoSignInSessionItem, $50f2bb780a45e70c$export$c12fab42a9a3e2a6 as isLogtoAccessTokenMap};
|
|
335
334
|
//# sourceMappingURL=module.js.map
|
package/lib/module.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":["/* eslint-disable max-lines */\nimport {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n fetchUserInfo,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n UserInfoResponse,\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, UserInfoResponse } 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 protected readonly adapter: ClientAdapter;\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<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\n if (this.logtoConfig.persistAccessToken) {\n void this.loadAccessTokenMap();\n }\n }\n\n async isAuthenticated() {\n return Boolean(await this.getIdToken());\n }\n\n async getRefreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n async getIdToken() {\n return this.adapter.storage.getItem('idToken');\n }\n\n // eslint-disable-next-line complexity\n async getAccessToken(resource?: string): Promise<string> {\n if (!(await this.getIdToken())) {\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 async getIdTokenClaims(): Promise<IdTokenClaims> {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(idToken);\n }\n\n async fetchUserInfo(): Promise<UserInfoResponse> {\n const { userinfoEndpoint } = await this.getOidcConfig();\n const accessToken = await this.getAccessToken();\n\n if (!accessToken) {\n throw new LogtoClientError('fetch_user_info_failed');\n }\n\n return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);\n }\n\n 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 await this.setSignInSession({ redirectUri, codeVerifier, state });\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(signInUri);\n }\n\n async isSignInRedirected(url: string): Promise<boolean> {\n const signInSession = await this.getSignInSession();\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 async handleSignInCallback(callbackUri: string) {\n const { logtoConfig, adapter } = this;\n const { requester } = adapter;\n const signInSession = await this.getSignInSession();\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 await this.saveCodeToken(codeTokenResponse);\n await this.setSignInSession(null);\n }\n\n async signOut(postLogoutRedirectUri?: string) {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n const refreshToken = await this.getRefreshToken();\n\n if (refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, 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,\n });\n\n this.accessTokenMap.clear();\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(url);\n }\n\n protected async getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>> {\n const jsonItem = await 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 async setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n await this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n await this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n private async setIdToken(idToken: Nullable<string>) {\n if (!idToken) {\n await this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('idToken', idToken);\n }\n\n private async setRefreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n await this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n const currentRefreshToken = await this.getRefreshToken();\n\n if (!currentRefreshToken) {\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: currentRefreshToken,\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\n await this.saveAccessTokenMap();\n await this.setRefreshToken(refreshToken);\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n await this.setIdToken(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 async saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n await this.setRefreshToken(refreshToken ?? null);\n await this.setIdToken(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 await this.saveAccessTokenMap();\n }\n\n private async 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 await this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private async loadAccessTokenMap() {\n const raw = await 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/* eslint-enable max-lines */\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 fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',\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"}
|
|
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":["/* eslint-disable max-lines */\nimport { ReservedScope } from '@logto/core-kit';\nimport {\n CodeTokenResponse,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n fetchUserInfo,\n generateSignInUri,\n generateSignOutUri,\n IdTokenClaims,\n Prompt,\n revoke,\n UserInfoResponse,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withDefaultScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\n\nimport { ClientAdapter } from './adapter';\nimport { LogtoClientError } from './errors';\nimport {\n AccessToken,\n isLogtoAccessTokenMap,\n isLogtoSignInSessionItem,\n LogtoConfig,\n LogtoSignInSessionItem,\n} from './types';\nimport { buildAccessTokenKey, getDiscoveryEndpoint } from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode, UserInfoResponse } 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';\nexport { ReservedScope, UserScope } from '@logto/core-kit';\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 protected readonly adapter: ClientAdapter;\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n\n constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withDefaultScopes(logtoConfig.scopes).split(' '),\n };\n this.adapter = adapter;\n\n void this.loadAccessTokenMap();\n }\n\n async isAuthenticated() {\n return Boolean(await this.getIdToken());\n }\n\n async getRefreshToken() {\n return this.adapter.storage.getItem('refreshToken');\n }\n\n async getIdToken() {\n return this.adapter.storage.getItem('idToken');\n }\n\n // eslint-disable-next-line complexity\n async getAccessToken(resource?: string): Promise<string> {\n if (!(await this.getIdToken())) {\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 async getIdTokenClaims(): Promise<IdTokenClaims> {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(idToken);\n }\n\n async fetchUserInfo(): Promise<UserInfoResponse> {\n const { userinfoEndpoint } = await this.getOidcConfig();\n const accessToken = await this.getAccessToken();\n\n if (!accessToken) {\n throw new LogtoClientError('fetch_user_info_failed');\n }\n\n return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);\n }\n\n 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 await this.setSignInSession({ redirectUri, codeVerifier, state });\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(signInUri);\n }\n\n async isSignInRedirected(url: string): Promise<boolean> {\n const signInSession = await this.getSignInSession();\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 async handleSignInCallback(callbackUri: string) {\n const { logtoConfig, adapter } = this;\n const { requester } = adapter;\n const signInSession = await this.getSignInSession();\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 await this.saveCodeToken(codeTokenResponse);\n await this.setSignInSession(null);\n }\n\n async signOut(postLogoutRedirectUri?: string) {\n const idToken = await this.getIdToken();\n\n if (!idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n const refreshToken = await this.getRefreshToken();\n\n if (refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, 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,\n });\n\n this.accessTokenMap.clear();\n await this.setRefreshToken(null);\n await this.setIdToken(null);\n\n this.adapter.navigate(url);\n }\n\n protected async getSignInSession(): Promise<Nullable<LogtoSignInSessionItem>> {\n const jsonItem = await this.adapter.storage.getItem('signInSession');\n\n if (!jsonItem) {\n return null;\n }\n\n const item: unknown = JSON.parse(jsonItem);\n\n if (!isLogtoSignInSessionItem(item)) {\n throw new LogtoClientError('sign_in_session.invalid');\n }\n\n return item;\n }\n\n protected async setSignInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n await this.adapter.storage.removeItem('signInSession');\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n await this.adapter.storage.setItem('signInSession', jsonItem);\n }\n\n private async setIdToken(idToken: Nullable<string>) {\n if (!idToken) {\n await this.adapter.storage.removeItem('idToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('idToken', idToken);\n }\n\n private async setRefreshToken(refreshToken: Nullable<string>) {\n if (!refreshToken) {\n await this.adapter.storage.removeItem('refreshToken');\n\n return;\n }\n\n await this.adapter.storage.setItem('refreshToken', refreshToken);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n const currentRefreshToken = await this.getRefreshToken();\n\n if (!currentRefreshToken) {\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: currentRefreshToken,\n resource,\n scopes: resource ? [ReservedScope.OfflineAccess] : 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\n await this.saveAccessTokenMap();\n await this.setRefreshToken(refreshToken);\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n await this.setIdToken(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 async saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n await this.setRefreshToken(refreshToken ?? null);\n await this.setIdToken(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 await this.saveAccessTokenMap();\n }\n\n private async saveAccessTokenMap() {\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 await this.adapter.storage.setItem('accessToken', JSON.stringify(data));\n }\n\n private async loadAccessTokenMap() {\n const raw = await this.adapter.storage.getItem('accessToken');\n\n if (!raw) {\n return;\n }\n\n try {\n const json: unknown = JSON.parse(raw);\n\n if (!isLogtoAccessTokenMap(json)) {\n return;\n }\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/* eslint-enable max-lines */\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 fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',\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 { isArbitraryObject, Prompt } from '@logto/js';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n appSecret?: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n};\n\nexport type AccessToken = {\n token: string;\n scope: string;\n expiresAt: number;\n};\n\nexport const isLogtoSignInSessionItem = (data: unknown): data is LogtoSignInSessionItem => {\n if (!isArbitraryObject(data)) {\n return false;\n }\n\n return ['redirectUri', 'codeVerifier', 'state'].every((key) => typeof data[key] === 'string');\n};\n\nexport const isLogtoAccessTokenMap = (data: unknown): data is Record<string, AccessToken> => {\n if (!isArbitraryObject(data)) {\n return false;\n }\n\n return Object.values(data).every((value) => {\n if (!isArbitraryObject(value)) {\n return false;\n }\n\n return (\n typeof value.token === 'string' &&\n typeof value.scope === 'string' &&\n typeof value.expiresAt === 'number'\n );\n });\n};\n\nexport type LogtoSignInSessionItem = {\n redirectUri: string;\n codeVerifier: string;\n state: string;\n};\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, isLogtoRequestError, 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 (!isLogtoRequestError(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.
|
|
3
|
+
"version": "1.0.0-beta.8",
|
|
4
4
|
"source": "./src/index.ts",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
"prepack": "pnpm test"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@logto/
|
|
32
|
+
"@logto/core-kit": "1.0.0-beta.14",
|
|
33
|
+
"@logto/js": "^1.0.0-beta.8",
|
|
33
34
|
"@silverhand/essentials": "^1.2.1",
|
|
34
35
|
"camelcase-keys": "^7.0.1",
|
|
35
36
|
"jose": "^4.3.8",
|
|
36
37
|
"lodash.get": "^4.4.2",
|
|
37
|
-
"lodash.once": "^4.1.1"
|
|
38
|
-
"superstruct": "^0.16.0"
|
|
38
|
+
"lodash.once": "^4.1.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@jest/types": "^27.5.1",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"publishConfig": {
|
|
68
68
|
"access": "public"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "1de579aab6fc3e7410e057fbb63f286f67e4f1dd"
|
|
71
71
|
}
|