@logto/browser 0.2.0 → 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +26 -24
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +199 -156
- package/lib/index.js.map +1 -0
- package/lib/module.js +280 -0
- package/lib/module.js.map +1 -0
- package/package.json +16 -6
- package/lib/errors.d.ts +0 -17
- package/lib/errors.js +0 -33
- package/lib/utils/index.d.ts +0 -5
- package/lib/utils/index.js +0 -15
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Infer } from
|
|
1
|
+
import { NormalizeKeyPaths, Nullable } from "@silverhand/essentials";
|
|
2
|
+
import { IdTokenClaims, Prompt, Requester } from "@logto/js";
|
|
3
|
+
import { Infer } from "superstruct";
|
|
4
|
+
declare const logtoClientErrorCodes: Readonly<{
|
|
5
|
+
sign_in_session: {
|
|
6
|
+
invalid: string;
|
|
7
|
+
not_found: string;
|
|
8
|
+
};
|
|
9
|
+
not_authenticated: string;
|
|
10
|
+
get_access_token_by_refresh_token_failed: string;
|
|
11
|
+
invalid_id_token: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;
|
|
14
|
+
export class LogtoClientError extends Error {
|
|
15
|
+
code: LogtoClientErrorCode;
|
|
16
|
+
data: unknown;
|
|
17
|
+
constructor(code: LogtoClientErrorCode, data?: unknown);
|
|
18
|
+
}
|
|
4
19
|
export type { IdTokenClaims, LogtoErrorCode } from '@logto/js';
|
|
5
|
-
export { LogtoError, OidcError } from '@logto/js';
|
|
6
|
-
export
|
|
7
|
-
export declare type LogtoConfig = {
|
|
20
|
+
export { LogtoError, OidcError, Prompt } from '@logto/js';
|
|
21
|
+
export type LogtoConfig = {
|
|
8
22
|
endpoint: string;
|
|
9
23
|
appId: string;
|
|
10
24
|
scopes?: string[];
|
|
@@ -12,12 +26,12 @@ export declare type LogtoConfig = {
|
|
|
12
26
|
prompt?: Prompt;
|
|
13
27
|
usingPersistStorage?: boolean;
|
|
14
28
|
};
|
|
15
|
-
export
|
|
29
|
+
export type AccessToken = {
|
|
16
30
|
token: string;
|
|
17
31
|
scope: string;
|
|
18
32
|
expiresAt: number;
|
|
19
33
|
};
|
|
20
|
-
export
|
|
34
|
+
export const LogtoSignInSessionItemSchema: import("superstruct").Struct<{
|
|
21
35
|
redirectUri: string;
|
|
22
36
|
codeVerifier: string;
|
|
23
37
|
state: string;
|
|
@@ -26,23 +40,14 @@ export declare const LogtoSignInSessionItemSchema: import("superstruct").Struct<
|
|
|
26
40
|
codeVerifier: import("superstruct").Struct<string, null>;
|
|
27
41
|
state: import("superstruct").Struct<string, null>;
|
|
28
42
|
}>;
|
|
29
|
-
export
|
|
43
|
+
export type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;
|
|
30
44
|
export default class LogtoClient {
|
|
31
45
|
protected readonly logtoConfig: LogtoConfig;
|
|
32
|
-
protected readonly getOidcConfig: () => Promise<import("@silverhand/essentials").KeysToCamelCase<
|
|
33
|
-
authorization_endpoint: string;
|
|
34
|
-
token_endpoint: string;
|
|
35
|
-
end_session_endpoint: string;
|
|
36
|
-
revocation_endpoint: string;
|
|
37
|
-
jwks_uri: string;
|
|
38
|
-
issuer: string;
|
|
39
|
-
}>>;
|
|
46
|
+
protected readonly getOidcConfig: () => Promise<import("@silverhand/essentials").KeysToCamelCase<import("@logto/js").OidcConfigSnakeCaseResponse>>;
|
|
40
47
|
protected readonly getJwtVerifyGetKey: () => Promise<import("jose/dist/types/types").GetKeyFunction<import("jose").JWSHeaderParameters, import("jose").FlattenedJWSInput>>;
|
|
41
48
|
protected readonly logtoStorageKey: string;
|
|
42
49
|
protected readonly requester: Requester;
|
|
43
50
|
protected readonly accessTokenMap: Map<string, AccessToken>;
|
|
44
|
-
private readonly getAccessTokenPromiseMap;
|
|
45
|
-
private _idToken;
|
|
46
51
|
constructor(logtoConfig: LogtoConfig, requester?: <T>(input: RequestInfo, init?: RequestInit | undefined) => Promise<T>);
|
|
47
52
|
get isAuthenticated(): boolean;
|
|
48
53
|
protected get signInSession(): Nullable<LogtoSignInSessionItem>;
|
|
@@ -57,9 +62,6 @@ export default class LogtoClient {
|
|
|
57
62
|
isSignInRedirected(url: string): boolean;
|
|
58
63
|
handleSignInCallback(callbackUri: string): Promise<void>;
|
|
59
64
|
signOut(postLogoutRedirectUri?: string): Promise<void>;
|
|
60
|
-
private getAccessTokenByRefreshToken;
|
|
61
|
-
private _getOidcConfig;
|
|
62
|
-
private _getJwtVerifyGetKey;
|
|
63
|
-
private verifyIdToken;
|
|
64
|
-
private saveCodeToken;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;AAGA,QAAA,MAAM;;;;;;;;EAQJ,CAAC;AAEH,mCAAmC,kBAAkB,4BAA4B,CAAC,CAAC;AAcnF,6BAA8B,SAAQ,KAAK;IACzC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;gBAEF,IAAI,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAAE,OAAO;CAKvD;AEFD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAG1D,0BAA0B;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,0BAA0B;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,OAAO,MAAM;;;;;;;;EAIX,CAAC;AAEH,qCAAqC,MAAM,mCAAmC,CAAC,CAAC;AAEhF;IACE,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,aAAa,mHAA6B;IAC7D,SAAS,CAAC,QAAQ,CAAC,kBAAkB,sIAAkC;IAEvE,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAC3C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAExC,SAAS,CAAC,QAAQ,CAAC,cAAc,2BAAkC;gBAKvD,WAAW,EAAE,WAAW,EAAE,SAAS,wEAAoB;IAWnE,IAAW,eAAe,YAEzB;IAED,SAAS,KAAK,aAAa,IAAI,SAAS,sBAAsB,CAAC,CAe9D;IAED,SAAS,KAAK,aAAa,CAAC,sBAAsB,EAAE,SAAS,sBAAsB,CAAC,EASnF;IAED,IAAI,YAAY,IAIuB,SAAS,MAAM,CAAC,CAFtD;IAED,OAAO,KAAK,YAAY,QAUvB;IAED,IAAI,OAAO,IAIkB,SAAS,MAAM,CAAC,CAF5C;IAED,OAAO,KAAK,OAAO,QAYlB;IAGY,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyCxD,gBAAgB,IAAI,aAAa;IAQ3B,MAAM,CAAC,WAAW,EAAE,MAAM;IAyBhC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAYlC,oBAAoB,CAAC,WAAW,EAAE,MAAM;IA6BxC,OAAO,CAAC,qBAAqB,CAAC,EAAE,MAAM;CA6GpD","sources":["packages/browser/src/src/errors.ts","packages/browser/src/src/utils/index.ts","packages/browser/src/src/index.ts","packages/browser/src/index.ts"],"sourcesContent":[null,null,null,"import {\n CodeTokenResponse,\n createRequester,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateCodeChallenge,\n generateCodeVerifier,\n generateSignInUri,\n generateSignOutUri,\n generateState,\n IdTokenClaims,\n Prompt,\n Requester,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert, Infer, string, type } from 'superstruct';\n\nimport { LogtoClientError } from './errors';\nimport {\n buildAccessTokenKey,\n buildIdTokenKey,\n buildLogtoKey,\n buildRefreshTokenKey,\n getDiscoveryEndpoint,\n} from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt } from '@logto/js';\nexport * from './errors';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n usingPersistStorage?: boolean;\n};\n\nexport type AccessToken = {\n token: string;\n scope: string;\n expiresAt: number; // Unix Timestamp in seconds\n};\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly logtoStorageKey: string;\n protected readonly requester: Requester;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, requester = createRequester()) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.logtoStorageKey = buildLogtoKey(logtoConfig.appId);\n this.requester = requester;\n this._idToken = localStorage.getItem(buildIdTokenKey(this.logtoStorageKey));\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = sessionStorage.getItem(this.logtoStorageKey);\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n sessionStorage.removeItem(this.logtoStorageKey);\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n sessionStorage.setItem(this.logtoStorageKey, jsonItem);\n }\n\n get refreshToken() {\n return localStorage.getItem(buildRefreshTokenKey(this.logtoStorageKey));\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n const refreshTokenKey = buildRefreshTokenKey(this.logtoStorageKey);\n\n if (!refreshToken) {\n localStorage.removeItem(refreshTokenKey);\n\n return;\n }\n\n localStorage.setItem(refreshTokenKey, refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n const idTokenKey = buildIdTokenKey(this.logtoStorageKey);\n\n if (!idToken) {\n localStorage.removeItem(idTokenKey);\n\n return;\n }\n\n localStorage.setItem(idTokenKey, idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n window.location.assign(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, requester } = this;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n window.location.assign(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n }\n}\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/lib/index.js
CHANGED
|
@@ -1,64 +1,118 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
var $2FOI4$logtojs = require("@logto/js");
|
|
2
|
+
var $2FOI4$jose = require("jose");
|
|
3
|
+
var $2FOI4$lodashonce = require("lodash.once");
|
|
4
|
+
var $2FOI4$superstruct = require("superstruct");
|
|
5
|
+
var $2FOI4$lodashget = require("lodash.get");
|
|
6
|
+
|
|
7
|
+
function $parcel$interopDefault(a) {
|
|
8
|
+
return a && a.__esModule ? a.default : a;
|
|
9
|
+
}
|
|
10
|
+
function $parcel$defineInteropFlag(a) {
|
|
11
|
+
Object.defineProperty(a, '__esModule', {value: true, configurable: true});
|
|
12
|
+
}
|
|
13
|
+
function $parcel$export(e, n, v, s) {
|
|
14
|
+
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
15
|
+
}
|
|
16
|
+
function $parcel$exportWildcard(dest, source) {
|
|
17
|
+
Object.keys(source).forEach(function(key) {
|
|
18
|
+
if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Object.defineProperty(dest, key, {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function get() {
|
|
25
|
+
return source[key];
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return dest;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
$parcel$defineInteropFlag(module.exports);
|
|
34
|
+
|
|
35
|
+
$parcel$export(module.exports, "LogtoSignInSessionItemSchema", () => $5a30d9203b683831$export$7b65a75f516b80e1);
|
|
36
|
+
$parcel$export(module.exports, "default", () => $5a30d9203b683831$export$2e2bcd8739ae039);
|
|
37
|
+
$parcel$export(module.exports, "LogtoError", () => $5a30d9203b683831$re_export$LogtoError);
|
|
38
|
+
$parcel$export(module.exports, "OidcError", () => $5a30d9203b683831$re_export$OidcError);
|
|
39
|
+
$parcel$export(module.exports, "Prompt", () => $2FOI4$logtojs.Prompt);
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
var $91774f8557d77d78$exports = {};
|
|
45
|
+
|
|
46
|
+
$parcel$export($91774f8557d77d78$exports, "LogtoClientError", () => $91774f8557d77d78$export$877962ca249b8fc8);
|
|
47
|
+
|
|
48
|
+
const $91774f8557d77d78$var$logtoClientErrorCodes = Object.freeze({
|
|
49
|
+
sign_in_session: {
|
|
50
|
+
invalid: "Invalid sign-in session.",
|
|
51
|
+
not_found: "Sign-in session not found."
|
|
52
|
+
},
|
|
53
|
+
not_authenticated: "Not authenticated.",
|
|
54
|
+
get_access_token_by_refresh_token_failed: "Failed to get access token by refresh token.",
|
|
55
|
+
invalid_id_token: "Invalid id token."
|
|
56
|
+
});
|
|
57
|
+
const $91774f8557d77d78$var$getMessageByErrorCode = (errorCode)=>{
|
|
58
|
+
// TODO: linear issue LOG-1419
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
60
|
+
const message = (0, ($parcel$interopDefault($2FOI4$lodashget)))($91774f8557d77d78$var$logtoClientErrorCodes, errorCode);
|
|
61
|
+
if (typeof message === "string") return message;
|
|
62
|
+
return errorCode;
|
|
14
63
|
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
class $91774f8557d77d78$export$877962ca249b8fc8 extends Error {
|
|
65
|
+
constructor(code, data){
|
|
66
|
+
super($91774f8557d77d78$var$getMessageByErrorCode(code));
|
|
67
|
+
this.code = code;
|
|
68
|
+
this.data = data;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
const $944e6f79cbd4667b$var$logtoStorageItemKeyPrefix = `logto`;
|
|
75
|
+
const $944e6f79cbd4667b$export$bdf1d4f122e17e7b = (key)=>`${$944e6f79cbd4667b$var$logtoStorageItemKeyPrefix}:${key}`;
|
|
76
|
+
const $944e6f79cbd4667b$export$79da00f3c12fcb3c = (logtoKey)=>`${logtoKey}:refreshToken`;
|
|
77
|
+
const $944e6f79cbd4667b$export$cdb4d35801155147 = (logtoKey)=>`${logtoKey}:idToken`;
|
|
78
|
+
const $944e6f79cbd4667b$export$8f595bd2a47bcea6 = (resource = "", scopes = [])=>`${scopes.slice().sort().join(" ")}@${resource}`;
|
|
79
|
+
const $944e6f79cbd4667b$export$5d9c34f69c80822b = (endpoint)=>new URL((0, $2FOI4$logtojs.discoveryPath), endpoint).toString();
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
const $5a30d9203b683831$export$7b65a75f516b80e1 = (0, $2FOI4$superstruct.type)({
|
|
85
|
+
redirectUri: (0, $2FOI4$superstruct.string)(),
|
|
86
|
+
codeVerifier: (0, $2FOI4$superstruct.string)(),
|
|
87
|
+
state: (0, $2FOI4$superstruct.string)()
|
|
31
88
|
});
|
|
32
|
-
class
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
89
|
+
class $5a30d9203b683831$export$2e2bcd8739ae039 {
|
|
90
|
+
getOidcConfig = (0, ($parcel$interopDefault($2FOI4$lodashonce)))(this._getOidcConfig);
|
|
91
|
+
getJwtVerifyGetKey = (0, ($parcel$interopDefault($2FOI4$lodashonce)))(this._getJwtVerifyGetKey);
|
|
92
|
+
accessTokenMap = new Map();
|
|
93
|
+
getAccessTokenPromiseMap = new Map();
|
|
94
|
+
constructor(logtoConfig, requester = (0, $2FOI4$logtojs.createRequester)()){
|
|
38
95
|
this.logtoConfig = {
|
|
39
96
|
...logtoConfig,
|
|
40
|
-
prompt: logtoConfig.prompt ??
|
|
41
|
-
scopes: (0,
|
|
97
|
+
prompt: logtoConfig.prompt ?? (0, $2FOI4$logtojs.Prompt).Consent,
|
|
98
|
+
scopes: (0, $2FOI4$logtojs.withReservedScopes)(logtoConfig.scopes).split(" ")
|
|
42
99
|
};
|
|
43
|
-
this.logtoStorageKey = (0,
|
|
100
|
+
this.logtoStorageKey = (0, $944e6f79cbd4667b$export$bdf1d4f122e17e7b)(logtoConfig.appId);
|
|
44
101
|
this.requester = requester;
|
|
45
|
-
this._idToken = localStorage.getItem((0,
|
|
102
|
+
this._idToken = localStorage.getItem((0, $944e6f79cbd4667b$export$cdb4d35801155147)(this.logtoStorageKey));
|
|
46
103
|
}
|
|
47
104
|
get isAuthenticated() {
|
|
48
105
|
return Boolean(this.idToken);
|
|
49
106
|
}
|
|
50
107
|
get signInSession() {
|
|
51
108
|
const jsonItem = sessionStorage.getItem(this.logtoStorageKey);
|
|
52
|
-
if (!jsonItem)
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
109
|
+
if (!jsonItem) return null;
|
|
55
110
|
try {
|
|
56
111
|
const item = JSON.parse(jsonItem);
|
|
57
|
-
(0,
|
|
112
|
+
(0, $2FOI4$superstruct.assert)(item, $5a30d9203b683831$export$7b65a75f516b80e1);
|
|
58
113
|
return item;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
throw new errors_1.LogtoClientError('sign_in_session.invalid', error);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("sign_in_session.invalid", error);
|
|
62
116
|
}
|
|
63
117
|
}
|
|
64
118
|
set signInSession(logtoSignInSessionItem) {
|
|
@@ -70,10 +124,10 @@ class LogtoClient {
|
|
|
70
124
|
sessionStorage.setItem(this.logtoStorageKey, jsonItem);
|
|
71
125
|
}
|
|
72
126
|
get refreshToken() {
|
|
73
|
-
return localStorage.getItem((0,
|
|
127
|
+
return localStorage.getItem((0, $944e6f79cbd4667b$export$79da00f3c12fcb3c)(this.logtoStorageKey));
|
|
74
128
|
}
|
|
75
129
|
set refreshToken(refreshToken) {
|
|
76
|
-
const refreshTokenKey = (0,
|
|
130
|
+
const refreshTokenKey = (0, $944e6f79cbd4667b$export$79da00f3c12fcb3c)(this.logtoStorageKey);
|
|
77
131
|
if (!refreshToken) {
|
|
78
132
|
localStorage.removeItem(refreshTokenKey);
|
|
79
133
|
return;
|
|
@@ -85,7 +139,7 @@ class LogtoClient {
|
|
|
85
139
|
}
|
|
86
140
|
set idToken(idToken) {
|
|
87
141
|
this._idToken = idToken;
|
|
88
|
-
const idTokenKey = (0,
|
|
142
|
+
const idTokenKey = (0, $944e6f79cbd4667b$export$cdb4d35801155147)(this.logtoStorageKey);
|
|
89
143
|
if (!idToken) {
|
|
90
144
|
localStorage.removeItem(idTokenKey);
|
|
91
145
|
return;
|
|
@@ -94,110 +148,94 @@ class LogtoClient {
|
|
|
94
148
|
}
|
|
95
149
|
// eslint-disable-next-line complexity
|
|
96
150
|
async getAccessToken(resource) {
|
|
97
|
-
if (!this.idToken)
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
const accessTokenKey = (0, utils_1.buildAccessTokenKey)(resource);
|
|
151
|
+
if (!this.idToken) throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("not_authenticated");
|
|
152
|
+
const accessTokenKey = (0, $944e6f79cbd4667b$export$8f595bd2a47bcea6)(resource);
|
|
101
153
|
const accessToken = this.accessTokenMap.get(accessTokenKey);
|
|
102
|
-
if (accessToken && accessToken.expiresAt > Date.now() / 1000)
|
|
103
|
-
return accessToken.token;
|
|
104
|
-
}
|
|
154
|
+
if (accessToken && accessToken.expiresAt > Date.now() / 1000) return accessToken.token;
|
|
105
155
|
// Since the access token has expired, delete it from the map.
|
|
106
|
-
if (accessToken)
|
|
107
|
-
this.accessTokenMap.delete(accessTokenKey);
|
|
108
|
-
}
|
|
156
|
+
if (accessToken) this.accessTokenMap.delete(accessTokenKey);
|
|
109
157
|
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (cachedPromise) {
|
|
115
|
-
return cachedPromise;
|
|
116
|
-
}
|
|
158
|
+
* Need to fetch a new access token using refresh token.
|
|
159
|
+
* Reuse the cached promise if exists.
|
|
160
|
+
*/ const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);
|
|
161
|
+
if (cachedPromise) return cachedPromise;
|
|
117
162
|
/**
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const promise = this.getAccessTokenByRefreshToken(resource);
|
|
163
|
+
* Create a new promise and cache in map to avoid race condition.
|
|
164
|
+
* Since we enable "refresh token rotation" by default,
|
|
165
|
+
* it will be problematic when calling multiple `getAccessToken()` closely.
|
|
166
|
+
*/ const promise = this.getAccessTokenByRefreshToken(resource);
|
|
123
167
|
this.getAccessTokenPromiseMap.set(accessTokenKey, promise);
|
|
124
168
|
const token = await promise;
|
|
125
169
|
this.getAccessTokenPromiseMap.delete(accessTokenKey);
|
|
126
170
|
return token;
|
|
127
171
|
}
|
|
128
172
|
getIdTokenClaims() {
|
|
129
|
-
if (!this.idToken)
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
return (0, js_1.decodeIdToken)(this.idToken);
|
|
173
|
+
if (!this.idToken) throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("not_authenticated");
|
|
174
|
+
return (0, $2FOI4$logtojs.decodeIdToken)(this.idToken);
|
|
133
175
|
}
|
|
134
176
|
async signIn(redirectUri) {
|
|
135
|
-
const { appId: clientId, resources, scopes } = this.logtoConfig;
|
|
136
|
-
const { authorizationEndpoint } = await this.getOidcConfig();
|
|
137
|
-
const codeVerifier = (0,
|
|
138
|
-
const codeChallenge = await (0,
|
|
139
|
-
const state = (0,
|
|
140
|
-
const signInUri = (0,
|
|
141
|
-
authorizationEndpoint,
|
|
142
|
-
clientId,
|
|
143
|
-
redirectUri,
|
|
144
|
-
codeChallenge,
|
|
145
|
-
state,
|
|
146
|
-
scopes,
|
|
147
|
-
resources,
|
|
177
|
+
const { appId: clientId , prompt: prompt , resources: resources , scopes: scopes } = this.logtoConfig;
|
|
178
|
+
const { authorizationEndpoint: authorizationEndpoint } = await this.getOidcConfig();
|
|
179
|
+
const codeVerifier = (0, $2FOI4$logtojs.generateCodeVerifier)();
|
|
180
|
+
const codeChallenge = await (0, $2FOI4$logtojs.generateCodeChallenge)(codeVerifier);
|
|
181
|
+
const state = (0, $2FOI4$logtojs.generateState)();
|
|
182
|
+
const signInUri = (0, $2FOI4$logtojs.generateSignInUri)({
|
|
183
|
+
authorizationEndpoint: authorizationEndpoint,
|
|
184
|
+
clientId: clientId,
|
|
185
|
+
redirectUri: redirectUri,
|
|
186
|
+
codeChallenge: codeChallenge,
|
|
187
|
+
state: state,
|
|
188
|
+
scopes: scopes,
|
|
189
|
+
resources: resources,
|
|
190
|
+
prompt: prompt
|
|
148
191
|
});
|
|
149
|
-
this.signInSession = {
|
|
192
|
+
this.signInSession = {
|
|
193
|
+
redirectUri: redirectUri,
|
|
194
|
+
codeVerifier: codeVerifier,
|
|
195
|
+
state: state
|
|
196
|
+
};
|
|
150
197
|
this.refreshToken = null;
|
|
151
198
|
this.idToken = null;
|
|
152
199
|
window.location.assign(signInUri);
|
|
153
200
|
}
|
|
154
201
|
isSignInRedirected(url) {
|
|
155
|
-
const { signInSession } = this;
|
|
156
|
-
if (!signInSession)
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
const { redirectUri } = signInSession;
|
|
160
|
-
const { origin, pathname } = new URL(url);
|
|
202
|
+
const { signInSession: signInSession } = this;
|
|
203
|
+
if (!signInSession) return false;
|
|
204
|
+
const { redirectUri: redirectUri } = signInSession;
|
|
205
|
+
const { origin: origin , pathname: pathname } = new URL(url);
|
|
161
206
|
return `${origin}${pathname}` === redirectUri;
|
|
162
207
|
}
|
|
163
208
|
async handleSignInCallback(callbackUri) {
|
|
164
|
-
const { signInSession, logtoConfig, requester } = this;
|
|
165
|
-
if (!signInSession)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const {
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
codeVerifier,
|
|
177
|
-
code,
|
|
209
|
+
const { signInSession: signInSession , logtoConfig: logtoConfig , requester: requester } = this;
|
|
210
|
+
if (!signInSession) throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("sign_in_session.not_found");
|
|
211
|
+
const { redirectUri: redirectUri , state: state , codeVerifier: codeVerifier } = signInSession;
|
|
212
|
+
const code = (0, $2FOI4$logtojs.verifyAndParseCodeFromCallbackUri)(callbackUri, redirectUri, state);
|
|
213
|
+
const { appId: clientId } = logtoConfig;
|
|
214
|
+
const { tokenEndpoint: tokenEndpoint } = await this.getOidcConfig();
|
|
215
|
+
const codeTokenResponse = await (0, $2FOI4$logtojs.fetchTokenByAuthorizationCode)({
|
|
216
|
+
clientId: clientId,
|
|
217
|
+
tokenEndpoint: tokenEndpoint,
|
|
218
|
+
redirectUri: redirectUri,
|
|
219
|
+
codeVerifier: codeVerifier,
|
|
220
|
+
code: code
|
|
178
221
|
}, requester);
|
|
179
222
|
await this.verifyIdToken(codeTokenResponse.idToken);
|
|
180
223
|
this.saveCodeToken(codeTokenResponse);
|
|
181
224
|
this.signInSession = null;
|
|
182
225
|
}
|
|
183
226
|
async signOut(postLogoutRedirectUri) {
|
|
184
|
-
if (!this.idToken)
|
|
185
|
-
|
|
227
|
+
if (!this.idToken) throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("not_authenticated");
|
|
228
|
+
const { appId: clientId } = this.logtoConfig;
|
|
229
|
+
const { endSessionEndpoint: endSessionEndpoint , revocationEndpoint: revocationEndpoint } = await this.getOidcConfig();
|
|
230
|
+
if (this.refreshToken) try {
|
|
231
|
+
await (0, $2FOI4$logtojs.revoke)(revocationEndpoint, clientId, this.refreshToken, this.requester);
|
|
232
|
+
} catch {
|
|
233
|
+
// Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
|
|
186
234
|
}
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
await (0, js_1.revoke)(revocationEndpoint, clientId, this.refreshToken, this.requester);
|
|
192
|
-
}
|
|
193
|
-
catch {
|
|
194
|
-
// Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const url = (0, js_1.generateSignOutUri)({
|
|
198
|
-
endSessionEndpoint,
|
|
199
|
-
postLogoutRedirectUri,
|
|
200
|
-
idToken: this.idToken,
|
|
235
|
+
const url = (0, $2FOI4$logtojs.generateSignOutUri)({
|
|
236
|
+
endSessionEndpoint: endSessionEndpoint,
|
|
237
|
+
postLogoutRedirectUri: postLogoutRedirectUri,
|
|
238
|
+
idToken: this.idToken
|
|
201
239
|
});
|
|
202
240
|
this.accessTokenMap.clear();
|
|
203
241
|
this.refreshToken = null;
|
|
@@ -205,24 +243,24 @@ class LogtoClient {
|
|
|
205
243
|
window.location.assign(url);
|
|
206
244
|
}
|
|
207
245
|
async getAccessTokenByRefreshToken(resource) {
|
|
208
|
-
if (!this.refreshToken)
|
|
209
|
-
throw new errors_1.LogtoClientError('not_authenticated');
|
|
210
|
-
}
|
|
246
|
+
if (!this.refreshToken) throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("not_authenticated");
|
|
211
247
|
try {
|
|
212
|
-
const accessTokenKey = (0,
|
|
213
|
-
const { appId: clientId
|
|
214
|
-
const { tokenEndpoint } = await this.getOidcConfig();
|
|
215
|
-
const { accessToken, refreshToken, idToken, scope, expiresIn } = await (0,
|
|
216
|
-
clientId,
|
|
217
|
-
tokenEndpoint,
|
|
248
|
+
const accessTokenKey = (0, $944e6f79cbd4667b$export$8f595bd2a47bcea6)(resource);
|
|
249
|
+
const { appId: clientId } = this.logtoConfig;
|
|
250
|
+
const { tokenEndpoint: tokenEndpoint } = await this.getOidcConfig();
|
|
251
|
+
const { accessToken: accessToken , refreshToken: refreshToken , idToken: idToken , scope: scope , expiresIn: expiresIn } = await (0, $2FOI4$logtojs.fetchTokenByRefreshToken)({
|
|
252
|
+
clientId: clientId,
|
|
253
|
+
tokenEndpoint: tokenEndpoint,
|
|
218
254
|
refreshToken: this.refreshToken,
|
|
219
|
-
resource,
|
|
220
|
-
scopes: resource ? [
|
|
255
|
+
resource: resource,
|
|
256
|
+
scopes: resource ? [
|
|
257
|
+
"offline_access"
|
|
258
|
+
] : undefined
|
|
221
259
|
}, this.requester);
|
|
222
260
|
this.accessTokenMap.set(accessTokenKey, {
|
|
223
261
|
token: accessToken,
|
|
224
|
-
scope,
|
|
225
|
-
expiresAt: Math.round(Date.now() / 1000) + expiresIn
|
|
262
|
+
scope: scope,
|
|
263
|
+
expiresAt: Math.round(Date.now() / 1000) + expiresIn
|
|
226
264
|
});
|
|
227
265
|
this.refreshToken = refreshToken;
|
|
228
266
|
if (idToken) {
|
|
@@ -230,38 +268,43 @@ class LogtoClient {
|
|
|
230
268
|
this.idToken = idToken;
|
|
231
269
|
}
|
|
232
270
|
return accessToken;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
throw new errors_1.LogtoClientError('get_access_token_by_refresh_token_failed', error);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("get_access_token_by_refresh_token_failed", error);
|
|
236
273
|
}
|
|
237
274
|
}
|
|
238
275
|
async _getOidcConfig() {
|
|
239
|
-
const { endpoint } = this.logtoConfig;
|
|
240
|
-
const discoveryEndpoint = (0,
|
|
241
|
-
return (0,
|
|
276
|
+
const { endpoint: endpoint } = this.logtoConfig;
|
|
277
|
+
const discoveryEndpoint = (0, $944e6f79cbd4667b$export$5d9c34f69c80822b)(endpoint);
|
|
278
|
+
return (0, $2FOI4$logtojs.fetchOidcConfig)(discoveryEndpoint, this.requester);
|
|
242
279
|
}
|
|
243
280
|
async _getJwtVerifyGetKey() {
|
|
244
|
-
const { jwksUri } = await this.getOidcConfig();
|
|
245
|
-
return (0,
|
|
281
|
+
const { jwksUri: jwksUri } = await this.getOidcConfig();
|
|
282
|
+
return (0, $2FOI4$jose.createRemoteJWKSet)(new URL(jwksUri));
|
|
246
283
|
}
|
|
247
284
|
async verifyIdToken(idToken) {
|
|
248
|
-
const { appId } = this.logtoConfig;
|
|
249
|
-
const { issuer } = await this.getOidcConfig();
|
|
285
|
+
const { appId: appId } = this.logtoConfig;
|
|
286
|
+
const { issuer: issuer } = await this.getOidcConfig();
|
|
250
287
|
const jwtVerifyGetKey = await this.getJwtVerifyGetKey();
|
|
251
288
|
try {
|
|
252
|
-
await (0,
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
throw new errors_1.LogtoClientError('invalid_id_token', error);
|
|
289
|
+
await (0, $2FOI4$logtojs.verifyIdToken)(idToken, appId, issuer, jwtVerifyGetKey);
|
|
290
|
+
} catch (error) {
|
|
291
|
+
throw new (0, $91774f8557d77d78$export$877962ca249b8fc8)("invalid_id_token", error);
|
|
256
292
|
}
|
|
257
293
|
}
|
|
258
|
-
saveCodeToken({ refreshToken, idToken, scope, accessToken, expiresIn
|
|
294
|
+
saveCodeToken({ refreshToken: refreshToken , idToken: idToken , scope: scope , accessToken: accessToken , expiresIn: expiresIn }) {
|
|
259
295
|
this.refreshToken = refreshToken ?? null;
|
|
260
296
|
this.idToken = idToken;
|
|
261
297
|
// NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
|
|
262
|
-
const accessTokenKey = (0,
|
|
298
|
+
const accessTokenKey = (0, $944e6f79cbd4667b$export$8f595bd2a47bcea6)();
|
|
263
299
|
const expiresAt = Date.now() / 1000 + expiresIn;
|
|
264
|
-
this.accessTokenMap.set(accessTokenKey, {
|
|
300
|
+
this.accessTokenMap.set(accessTokenKey, {
|
|
301
|
+
token: accessToken,
|
|
302
|
+
scope: scope,
|
|
303
|
+
expiresAt: expiresAt
|
|
304
|
+
});
|
|
265
305
|
}
|
|
266
306
|
}
|
|
267
|
-
exports
|
|
307
|
+
$parcel$exportWildcard(module.exports, $91774f8557d77d78$exports);
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;ACAA;AAGA,MAAM,2CAAqB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,eAAe,EAAE;QACf,OAAO,EAAE,0BAA0B;QACnC,SAAS,EAAE,4BAA4B;KACxC;IACD,iBAAiB,EAAE,oBAAoB;IACvC,wCAAwC,EAAE,8CAA8C;IACxF,gBAAgB,EAAE,mBAAmB;CACtC,CAAC,AAAC;AAIH,MAAM,2CAAqB,GAAG,CAAC,SAA+B,GAAa;IACzE,8BAA8B;IAC9B,mEAAmE;IACnE,MAAM,OAAO,GAAG,CAAA,GAAA,0CAAG,CAAA,CAAC,2CAAqB,EAAE,SAAS,CAAC,AAAC;IAEtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAC7B,OAAO,OAAO,CAAC;IAGjB,OAAO,SAAS,CAAC;CAClB,AAAC;AAEK,MAAM,yCAAgB,SAAS,KAAK;IAIzC,YAAY,IAA0B,EAAE,IAAc,CAAE;QACtD,KAAK,CAAC,2CAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;KAClB;CACF;;;ACpCD;AAEA,MAAM,+CAAyB,GAAG,CAAC,KAAK,CAAC,AAAC;AACnC,MAAM,yCAAa,GAAG,CAAC,GAAW,GAAa,CAAC,EAAE,+CAAyB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,AAAC;AACrF,MAAM,yCAAoB,GAAG,CAAC,QAAgB,GAAK,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,AAAC;AAC9E,MAAM,yCAAe,GAAG,CAAC,QAAgB,GAAK,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,AAAC;AAEpE,MAAM,yCAAmB,GAAG,CAAC,QAAQ,GAAG,EAAE,EAAE,MAAgB,GAAG,EAAE,GACtE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,AAAC;AAE5C,MAAM,yCAAoB,GAAG,CAAC,QAAgB,GACnD,IAAI,GAAG,CAAC,CAAA,GAAA,4BAAa,CAAA,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,AAAC;;;;;AF0CvC,MAAM,yCAA4B,GAAG,CAAA,GAAA,uBAAI,CAAA,CAAC;IAC/C,WAAW,EAAE,CAAA,GAAA,yBAAM,CAAA,EAAE;IACrB,YAAY,EAAE,CAAA,GAAA,yBAAM,CAAA,EAAE;IACtB,KAAK,EAAE,CAAA,GAAA,yBAAM,CAAA,EAAE;CAChB,CAAC,AAAC;AAIY;IAEb,AAAmB,aAAa,GAAG,CAAA,GAAA,2CAAI,CAAA,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7D,AAAmB,kBAAkB,GAAG,CAAA,GAAA,2CAAI,CAAA,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAKvE,AAAmB,cAAc,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEnE,AAAiB,wBAAwB,GAAG,IAAI,GAAG,EAA2B,CAAC;IAG/E,YAAY,WAAwB,EAAE,SAAS,GAAG,CAAA,GAAA,8BAAe,CAAA,EAAE,CAAE;QACnE,IAAI,CAAC,WAAW,GAAG;YACjB,GAAG,WAAW;YACd,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,CAAA,GAAA,qBAAM,CAAA,CAAC,OAAO;YAC5C,MAAM,EAAE,CAAA,GAAA,iCAAkB,CAAA,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;SAC1D,CAAC;QACF,IAAI,CAAC,eAAe,GAAG,CAAA,GAAA,yCAAa,CAAA,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA,GAAA,yCAAe,CAAA,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;KAC7E;IAED,IAAW,eAAe,GAAG;QAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KAC9B;IAED,IAAc,aAAa,GAAqC;QAC9D,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,AAAC;QAE9D,IAAI,CAAC,QAAQ,EACX,OAAO,IAAI,CAAC;QAGd,IAAI;YACF,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,AAAC;YAC3C,CAAA,GAAA,yBAAM,CAAA,CAAC,IAAI,EAAE,yCAA4B,CAAC,CAAC;YAE3C,OAAO,IAAI,CAAC;SACb,CAAC,OAAO,KAAK,EAAW;YACvB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;SAC9D;KACF;IAED,IAAc,aAAa,CAAC,sBAAwD,EAAE;QACpF,IAAI,CAAC,sBAAsB,EAAE;YAC3B,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAEhD,OAAO;SACR;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,AAAC;QACxD,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;KACxD;IAED,IAAI,YAAY,GAAG;QACjB,OAAO,YAAY,CAAC,OAAO,CAAC,CAAA,GAAA,yCAAoB,CAAA,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;KACzE;IAED,IAAY,YAAY,CAAC,YAA8B,EAAE;QACvD,MAAM,eAAe,GAAG,CAAA,GAAA,yCAAoB,CAAA,CAAC,IAAI,CAAC,eAAe,CAAC,AAAC;QAEnE,IAAI,CAAC,YAAY,EAAE;YACjB,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAEzC,OAAO;SACR;QAED,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;KACrD;IAED,IAAI,OAAO,GAAG;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;KACtB;IAED,IAAY,OAAO,CAAC,OAAyB,EAAE;QAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QAExB,MAAM,UAAU,GAAG,CAAA,GAAA,yCAAe,CAAA,CAAC,IAAI,CAAC,eAAe,CAAC,AAAC;QAEzD,IAAI,CAAC,OAAO,EAAE;YACZ,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAEpC,OAAO;SACR;QAED,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;KAC3C;IAED,sCAAsC;IACtC,MAAa,cAAc,CAAC,QAAiB,EAAmB;QAC9D,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,MAAM,cAAc,GAAG,CAAA,GAAA,yCAAmB,CAAA,CAAC,QAAQ,CAAC,AAAC;QACrD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,AAAC;QAE5D,IAAI,WAAW,IAAI,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAC1D,OAAO,WAAW,CAAC,KAAK,CAAC;QAG3B,8DAA8D;QAC9D,IAAI,WAAW,EACb,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAG7C;;;OAGG,CACH,MAAM,aAAa,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,cAAc,CAAC,AAAC;QAExE,IAAI,aAAa,EACf,OAAO,aAAa,CAAC;QAGvB;;;;OAIG,CACH,MAAM,OAAO,GAAG,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,AAAC;QAC5D,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAE3D,MAAM,KAAK,GAAG,MAAM,OAAO,AAAC;QAC5B,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAErD,OAAO,KAAK,CAAC;KACd;IAED,AAAO,gBAAgB,GAAkB;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,OAAO,CAAA,GAAA,4BAAa,CAAA,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KACpC;IAED,MAAa,MAAM,CAAC,WAAmB,EAAE;QACvC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,UAAE,MAAM,CAAA,aAAE,SAAS,CAAA,UAAE,MAAM,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QACxE,MAAM,yBAAE,qBAAqB,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAC7D,MAAM,YAAY,GAAG,CAAA,GAAA,mCAAoB,CAAA,EAAE,AAAC;QAC5C,MAAM,aAAa,GAAG,MAAM,CAAA,GAAA,oCAAqB,CAAA,CAAC,YAAY,CAAC,AAAC;QAChE,MAAM,KAAK,GAAG,CAAA,GAAA,4BAAa,CAAA,EAAE,AAAC;QAE9B,MAAM,SAAS,GAAG,CAAA,GAAA,gCAAiB,CAAA,CAAC;mCAClC,qBAAqB;sBACrB,QAAQ;yBACR,WAAW;2BACX,aAAa;mBACb,KAAK;oBACL,MAAM;uBACN,SAAS;oBACT,MAAM;SACP,CAAC,AAAC;QAEH,IAAI,CAAC,aAAa,GAAG;yBAAE,WAAW;0BAAE,YAAY;mBAAE,KAAK;SAAE,CAAC;QAC1D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;KACnC;IAED,AAAO,kBAAkB,CAAC,GAAW,EAAW;QAC9C,MAAM,iBAAE,aAAa,CAAA,EAAE,GAAG,IAAI,AAAC;QAE/B,IAAI,CAAC,aAAa,EAChB,OAAO,KAAK,CAAC;QAEf,MAAM,eAAE,WAAW,CAAA,EAAE,GAAG,aAAa,AAAC;QACtC,MAAM,UAAE,MAAM,CAAA,YAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,AAAC;QAE1C,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,KAAK,WAAW,CAAC;KAC/C;IAED,MAAa,oBAAoB,CAAC,WAAmB,EAAE;QACrD,MAAM,iBAAE,aAAa,CAAA,eAAE,WAAW,CAAA,aAAE,SAAS,CAAA,EAAE,GAAG,IAAI,AAAC;QAEvD,IAAI,CAAC,aAAa,EAChB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,2BAA2B,CAAC,CAAC;QAG1D,MAAM,eAAE,WAAW,CAAA,SAAE,KAAK,CAAA,gBAAE,YAAY,CAAA,EAAE,GAAG,aAAa,AAAC;QAC3D,MAAM,IAAI,GAAG,CAAA,GAAA,gDAAiC,CAAA,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,AAAC;QAEhF,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,EAAE,GAAG,WAAW,AAAC;QACxC,MAAM,iBAAE,aAAa,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QACrD,MAAM,iBAAiB,GAAG,MAAM,CAAA,GAAA,4CAA6B,CAAA,CAC3D;sBACE,QAAQ;2BACR,aAAa;yBACb,WAAW;0BACX,YAAY;kBACZ,IAAI;SACL,EACD,SAAS,CACV,AAAC;QAEF,MAAM,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;KAC3B;IAED,MAAa,OAAO,CAAC,qBAA8B,EAAE;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QAC7C,MAAM,sBAAE,kBAAkB,CAAA,sBAAE,kBAAkB,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAE9E,IAAI,IAAI,CAAC,YAAY,EACnB,IAAI;YACF,MAAM,CAAA,GAAA,qBAAM,CAAA,CAAC,kBAAkB,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;SAC/E,CAAC,OAAM;QACN,yGAAyG;SAC1G;QAGH,MAAM,GAAG,GAAG,CAAA,GAAA,iCAAkB,CAAA,CAAC;gCAC7B,kBAAkB;mCAClB,qBAAqB;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,AAAC;QAEH,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KAC7B;IAED,MAAc,4BAA4B,CAAC,QAAiB,EAAmB;QAC7E,IAAI,CAAC,IAAI,CAAC,YAAY,EACpB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,mBAAmB,CAAC,CAAC;QAGlD,IAAI;YACF,MAAM,cAAc,GAAG,CAAA,GAAA,yCAAmB,CAAA,CAAC,QAAQ,CAAC,AAAC;YACrD,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;YAC7C,MAAM,iBAAE,aAAa,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;YACrD,MAAM,eAAE,WAAW,CAAA,gBAAE,YAAY,CAAA,WAAE,OAAO,CAAA,SAAE,KAAK,CAAA,aAAE,SAAS,CAAA,EAAE,GAC5D,MAAM,CAAA,GAAA,uCAAwB,CAAA,CAC5B;0BACE,QAAQ;+BACR,aAAa;gBACb,YAAY,EAAE,IAAI,CAAC,YAAY;0BAC/B,QAAQ;gBACR,MAAM,EAAE,QAAQ,GAAG;oBAAC,gBAAgB;iBAAC,GAAG,SAAS;aAClD,EACD,IAAI,CAAC,SAAS,CACf,AAAC;YAEJ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE;gBACtC,KAAK,EAAE,WAAW;uBAClB,KAAK;gBACL,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS;aACrD,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;YAEjC,IAAI,OAAO,EAAE;gBACX,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;aACxB;YAED,OAAO,WAAW,CAAC;SACpB,CAAC,OAAO,KAAK,EAAW;YACvB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;SAC/E;KACF;IAED,MAAc,cAAc,GAAG;QAC7B,MAAM,YAAE,QAAQ,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QACtC,MAAM,iBAAiB,GAAG,CAAA,GAAA,yCAAoB,CAAA,CAAC,QAAQ,CAAC,AAAC;QAEzD,OAAO,CAAA,GAAA,8BAAe,CAAA,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;KAC3D;IAED,MAAc,mBAAmB,GAAG;QAClC,MAAM,WAAE,OAAO,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAE/C,OAAO,CAAA,GAAA,8BAAkB,CAAA,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;KAC7C;IAED,MAAc,aAAa,CAAC,OAAe,EAAE;QAC3C,MAAM,SAAE,KAAK,CAAA,EAAE,GAAG,IAAI,CAAC,WAAW,AAAC;QACnC,MAAM,UAAE,MAAM,CAAA,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,AAAC;QAC9C,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,AAAC;QAExD,IAAI;YACF,MAAM,CAAA,GAAA,4BAAa,CAAA,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;SAC9D,CAAC,OAAO,KAAK,EAAW;YACvB,MAAM,IAAI,CAAA,GAAA,yCAAgB,CAAA,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;SACvD;KACF;IAED,AAAQ,aAAa,CAAC,gBACpB,YAAY,CAAA,WACZ,OAAO,CAAA,SACP,KAAK,CAAA,eACL,WAAW,CAAA,aACX,SAAS,CAAA,EACS,EAAE;QACpB,IAAI,CAAC,YAAY,GAAG,YAAY,IAAI,IAAI,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,8EAA8E;QAC9E,MAAM,cAAc,GAAG,CAAA,GAAA,yCAAmB,CAAA,EAAE,AAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,AAAC;QAChD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE;YAAE,KAAK,EAAE,WAAW;mBAAE,KAAK;uBAAE,SAAS;SAAE,CAAC,CAAC;KACnF;CACF","sources":["packages/browser/src/index.ts","packages/browser/src/errors.ts","packages/browser/src/utils/index.ts"],"sourcesContent":["import {\n CodeTokenResponse,\n createRequester,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateCodeChallenge,\n generateCodeVerifier,\n generateSignInUri,\n generateSignOutUri,\n generateState,\n IdTokenClaims,\n Prompt,\n Requester,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert, Infer, string, type } from 'superstruct';\n\nimport { LogtoClientError } from './errors';\nimport {\n buildAccessTokenKey,\n buildIdTokenKey,\n buildLogtoKey,\n buildRefreshTokenKey,\n getDiscoveryEndpoint,\n} from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt } from '@logto/js';\nexport * from './errors';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n usingPersistStorage?: boolean;\n};\n\nexport type AccessToken = {\n token: string;\n scope: string;\n expiresAt: number; // Unix Timestamp in seconds\n};\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly logtoStorageKey: string;\n protected readonly requester: Requester;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, requester = createRequester()) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.logtoStorageKey = buildLogtoKey(logtoConfig.appId);\n this.requester = requester;\n this._idToken = localStorage.getItem(buildIdTokenKey(this.logtoStorageKey));\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = sessionStorage.getItem(this.logtoStorageKey);\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n sessionStorage.removeItem(this.logtoStorageKey);\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n sessionStorage.setItem(this.logtoStorageKey, jsonItem);\n }\n\n get refreshToken() {\n return localStorage.getItem(buildRefreshTokenKey(this.logtoStorageKey));\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n const refreshTokenKey = buildRefreshTokenKey(this.logtoStorageKey);\n\n if (!refreshToken) {\n localStorage.removeItem(refreshTokenKey);\n\n return;\n }\n\n localStorage.setItem(refreshTokenKey, refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n const idTokenKey = buildIdTokenKey(this.logtoStorageKey);\n\n if (!idToken) {\n localStorage.removeItem(idTokenKey);\n\n return;\n }\n\n localStorage.setItem(idTokenKey, idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n window.location.assign(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, requester } = this;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n window.location.assign(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n }\n}\n","import { NormalizeKeyPaths } from '@silverhand/essentials';\nimport get from 'lodash.get';\n\nconst logtoClientErrorCodes = Object.freeze({\n sign_in_session: {\n invalid: 'Invalid sign-in session.',\n not_found: 'Sign-in session not found.',\n },\n not_authenticated: 'Not authenticated.',\n get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',\n invalid_id_token: 'Invalid id token.',\n});\n\nexport type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;\n\nconst getMessageByErrorCode = (errorCode: LogtoClientErrorCode): string => {\n // TODO: linear issue LOG-1419\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 { discoveryPath } from '@logto/js';\n\nconst logtoStorageItemKeyPrefix = `logto`;\nexport const buildLogtoKey = (key: string): string => `${logtoStorageItemKeyPrefix}:${key}`;\nexport const buildRefreshTokenKey = (logtoKey: string) => `${logtoKey}:refreshToken`;\nexport const buildIdTokenKey = (logtoKey: string) => `${logtoKey}:idToken`;\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"],"names":[],"version":3,"file":"index.js.map"}
|
package/lib/module.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import {createRequester as $ElS14$createRequester, Prompt as $90df2ab0e44b5eba$import$5548085c5b0a2ee3$83716a4aa1642908, withReservedScopes as $ElS14$withReservedScopes, decodeIdToken as $ElS14$decodeIdToken, generateCodeVerifier as $ElS14$generateCodeVerifier, generateCodeChallenge as $ElS14$generateCodeChallenge, generateState as $ElS14$generateState, generateSignInUri as $ElS14$generateSignInUri, verifyAndParseCodeFromCallbackUri as $ElS14$verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode as $ElS14$fetchTokenByAuthorizationCode, revoke as $ElS14$revoke, generateSignOutUri as $ElS14$generateSignOutUri, fetchTokenByRefreshToken as $ElS14$fetchTokenByRefreshToken, fetchOidcConfig as $ElS14$fetchOidcConfig, verifyIdToken as $ElS14$verifyIdToken, LogtoError as $90df2ab0e44b5eba$re_export$LogtoError, OidcError as $90df2ab0e44b5eba$re_export$OidcError, discoveryPath as $ElS14$discoveryPath} from "@logto/js";
|
|
2
|
+
import {createRemoteJWKSet as $ElS14$createRemoteJWKSet} from "jose";
|
|
3
|
+
import $ElS14$lodashonce from "lodash.once";
|
|
4
|
+
import {type as $ElS14$type, string as $ElS14$string, assert as $ElS14$assert} from "superstruct";
|
|
5
|
+
import $ElS14$lodashget from "lodash.get";
|
|
6
|
+
|
|
7
|
+
function $parcel$export(e, n, v, s) {
|
|
8
|
+
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
var $092943c955830b14$exports = {};
|
|
15
|
+
|
|
16
|
+
$parcel$export($092943c955830b14$exports, "LogtoClientError", () => $092943c955830b14$export$877962ca249b8fc8);
|
|
17
|
+
|
|
18
|
+
const $092943c955830b14$var$logtoClientErrorCodes = Object.freeze({
|
|
19
|
+
sign_in_session: {
|
|
20
|
+
invalid: "Invalid sign-in session.",
|
|
21
|
+
not_found: "Sign-in session not found."
|
|
22
|
+
},
|
|
23
|
+
not_authenticated: "Not authenticated.",
|
|
24
|
+
get_access_token_by_refresh_token_failed: "Failed to get access token by refresh token.",
|
|
25
|
+
invalid_id_token: "Invalid id token."
|
|
26
|
+
});
|
|
27
|
+
const $092943c955830b14$var$getMessageByErrorCode = (errorCode)=>{
|
|
28
|
+
// TODO: linear issue LOG-1419
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
30
|
+
const message = (0, $ElS14$lodashget)($092943c955830b14$var$logtoClientErrorCodes, errorCode);
|
|
31
|
+
if (typeof message === "string") return message;
|
|
32
|
+
return errorCode;
|
|
33
|
+
};
|
|
34
|
+
class $092943c955830b14$export$877962ca249b8fc8 extends Error {
|
|
35
|
+
constructor(code, data){
|
|
36
|
+
super($092943c955830b14$var$getMessageByErrorCode(code));
|
|
37
|
+
this.code = code;
|
|
38
|
+
this.data = data;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const $2f0dba05fbbfeb85$var$logtoStorageItemKeyPrefix = `logto`;
|
|
45
|
+
const $2f0dba05fbbfeb85$export$bdf1d4f122e17e7b = (key)=>`${$2f0dba05fbbfeb85$var$logtoStorageItemKeyPrefix}:${key}`;
|
|
46
|
+
const $2f0dba05fbbfeb85$export$79da00f3c12fcb3c = (logtoKey)=>`${logtoKey}:refreshToken`;
|
|
47
|
+
const $2f0dba05fbbfeb85$export$cdb4d35801155147 = (logtoKey)=>`${logtoKey}:idToken`;
|
|
48
|
+
const $2f0dba05fbbfeb85$export$8f595bd2a47bcea6 = (resource = "", scopes = [])=>`${scopes.slice().sort().join(" ")}@${resource}`;
|
|
49
|
+
const $2f0dba05fbbfeb85$export$5d9c34f69c80822b = (endpoint)=>new URL((0, $ElS14$discoveryPath), endpoint).toString();
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
const $90df2ab0e44b5eba$export$7b65a75f516b80e1 = (0, $ElS14$type)({
|
|
55
|
+
redirectUri: (0, $ElS14$string)(),
|
|
56
|
+
codeVerifier: (0, $ElS14$string)(),
|
|
57
|
+
state: (0, $ElS14$string)()
|
|
58
|
+
});
|
|
59
|
+
class $90df2ab0e44b5eba$export$2e2bcd8739ae039 {
|
|
60
|
+
getOidcConfig = (0, $ElS14$lodashonce)(this._getOidcConfig);
|
|
61
|
+
getJwtVerifyGetKey = (0, $ElS14$lodashonce)(this._getJwtVerifyGetKey);
|
|
62
|
+
accessTokenMap = new Map();
|
|
63
|
+
getAccessTokenPromiseMap = new Map();
|
|
64
|
+
constructor(logtoConfig, requester = (0, $ElS14$createRequester)()){
|
|
65
|
+
this.logtoConfig = {
|
|
66
|
+
...logtoConfig,
|
|
67
|
+
prompt: logtoConfig.prompt ?? (0, $90df2ab0e44b5eba$import$5548085c5b0a2ee3$83716a4aa1642908).Consent,
|
|
68
|
+
scopes: (0, $ElS14$withReservedScopes)(logtoConfig.scopes).split(" ")
|
|
69
|
+
};
|
|
70
|
+
this.logtoStorageKey = (0, $2f0dba05fbbfeb85$export$bdf1d4f122e17e7b)(logtoConfig.appId);
|
|
71
|
+
this.requester = requester;
|
|
72
|
+
this._idToken = localStorage.getItem((0, $2f0dba05fbbfeb85$export$cdb4d35801155147)(this.logtoStorageKey));
|
|
73
|
+
}
|
|
74
|
+
get isAuthenticated() {
|
|
75
|
+
return Boolean(this.idToken);
|
|
76
|
+
}
|
|
77
|
+
get signInSession() {
|
|
78
|
+
const jsonItem = sessionStorage.getItem(this.logtoStorageKey);
|
|
79
|
+
if (!jsonItem) return null;
|
|
80
|
+
try {
|
|
81
|
+
const item = JSON.parse(jsonItem);
|
|
82
|
+
(0, $ElS14$assert)(item, $90df2ab0e44b5eba$export$7b65a75f516b80e1);
|
|
83
|
+
return item;
|
|
84
|
+
} catch (error) {
|
|
85
|
+
throw new (0, $092943c955830b14$export$877962ca249b8fc8)("sign_in_session.invalid", error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
set signInSession(logtoSignInSessionItem) {
|
|
89
|
+
if (!logtoSignInSessionItem) {
|
|
90
|
+
sessionStorage.removeItem(this.logtoStorageKey);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const jsonItem = JSON.stringify(logtoSignInSessionItem);
|
|
94
|
+
sessionStorage.setItem(this.logtoStorageKey, jsonItem);
|
|
95
|
+
}
|
|
96
|
+
get refreshToken() {
|
|
97
|
+
return localStorage.getItem((0, $2f0dba05fbbfeb85$export$79da00f3c12fcb3c)(this.logtoStorageKey));
|
|
98
|
+
}
|
|
99
|
+
set refreshToken(refreshToken) {
|
|
100
|
+
const refreshTokenKey = (0, $2f0dba05fbbfeb85$export$79da00f3c12fcb3c)(this.logtoStorageKey);
|
|
101
|
+
if (!refreshToken) {
|
|
102
|
+
localStorage.removeItem(refreshTokenKey);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
localStorage.setItem(refreshTokenKey, refreshToken);
|
|
106
|
+
}
|
|
107
|
+
get idToken() {
|
|
108
|
+
return this._idToken;
|
|
109
|
+
}
|
|
110
|
+
set idToken(idToken) {
|
|
111
|
+
this._idToken = idToken;
|
|
112
|
+
const idTokenKey = (0, $2f0dba05fbbfeb85$export$cdb4d35801155147)(this.logtoStorageKey);
|
|
113
|
+
if (!idToken) {
|
|
114
|
+
localStorage.removeItem(idTokenKey);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
localStorage.setItem(idTokenKey, idToken);
|
|
118
|
+
}
|
|
119
|
+
// eslint-disable-next-line complexity
|
|
120
|
+
async getAccessToken(resource) {
|
|
121
|
+
if (!this.idToken) throw new (0, $092943c955830b14$export$877962ca249b8fc8)("not_authenticated");
|
|
122
|
+
const accessTokenKey = (0, $2f0dba05fbbfeb85$export$8f595bd2a47bcea6)(resource);
|
|
123
|
+
const accessToken = this.accessTokenMap.get(accessTokenKey);
|
|
124
|
+
if (accessToken && accessToken.expiresAt > Date.now() / 1000) return accessToken.token;
|
|
125
|
+
// Since the access token has expired, delete it from the map.
|
|
126
|
+
if (accessToken) this.accessTokenMap.delete(accessTokenKey);
|
|
127
|
+
/**
|
|
128
|
+
* Need to fetch a new access token using refresh token.
|
|
129
|
+
* Reuse the cached promise if exists.
|
|
130
|
+
*/ const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);
|
|
131
|
+
if (cachedPromise) return cachedPromise;
|
|
132
|
+
/**
|
|
133
|
+
* Create a new promise and cache in map to avoid race condition.
|
|
134
|
+
* Since we enable "refresh token rotation" by default,
|
|
135
|
+
* it will be problematic when calling multiple `getAccessToken()` closely.
|
|
136
|
+
*/ const promise = this.getAccessTokenByRefreshToken(resource);
|
|
137
|
+
this.getAccessTokenPromiseMap.set(accessTokenKey, promise);
|
|
138
|
+
const token = await promise;
|
|
139
|
+
this.getAccessTokenPromiseMap.delete(accessTokenKey);
|
|
140
|
+
return token;
|
|
141
|
+
}
|
|
142
|
+
getIdTokenClaims() {
|
|
143
|
+
if (!this.idToken) throw new (0, $092943c955830b14$export$877962ca249b8fc8)("not_authenticated");
|
|
144
|
+
return (0, $ElS14$decodeIdToken)(this.idToken);
|
|
145
|
+
}
|
|
146
|
+
async signIn(redirectUri) {
|
|
147
|
+
const { appId: clientId , prompt: prompt , resources: resources , scopes: scopes } = this.logtoConfig;
|
|
148
|
+
const { authorizationEndpoint: authorizationEndpoint } = await this.getOidcConfig();
|
|
149
|
+
const codeVerifier = (0, $ElS14$generateCodeVerifier)();
|
|
150
|
+
const codeChallenge = await (0, $ElS14$generateCodeChallenge)(codeVerifier);
|
|
151
|
+
const state = (0, $ElS14$generateState)();
|
|
152
|
+
const signInUri = (0, $ElS14$generateSignInUri)({
|
|
153
|
+
authorizationEndpoint: authorizationEndpoint,
|
|
154
|
+
clientId: clientId,
|
|
155
|
+
redirectUri: redirectUri,
|
|
156
|
+
codeChallenge: codeChallenge,
|
|
157
|
+
state: state,
|
|
158
|
+
scopes: scopes,
|
|
159
|
+
resources: resources,
|
|
160
|
+
prompt: prompt
|
|
161
|
+
});
|
|
162
|
+
this.signInSession = {
|
|
163
|
+
redirectUri: redirectUri,
|
|
164
|
+
codeVerifier: codeVerifier,
|
|
165
|
+
state: state
|
|
166
|
+
};
|
|
167
|
+
this.refreshToken = null;
|
|
168
|
+
this.idToken = null;
|
|
169
|
+
window.location.assign(signInUri);
|
|
170
|
+
}
|
|
171
|
+
isSignInRedirected(url) {
|
|
172
|
+
const { signInSession: signInSession } = this;
|
|
173
|
+
if (!signInSession) return false;
|
|
174
|
+
const { redirectUri: redirectUri } = signInSession;
|
|
175
|
+
const { origin: origin , pathname: pathname } = new URL(url);
|
|
176
|
+
return `${origin}${pathname}` === redirectUri;
|
|
177
|
+
}
|
|
178
|
+
async handleSignInCallback(callbackUri) {
|
|
179
|
+
const { signInSession: signInSession , logtoConfig: logtoConfig , requester: requester } = this;
|
|
180
|
+
if (!signInSession) throw new (0, $092943c955830b14$export$877962ca249b8fc8)("sign_in_session.not_found");
|
|
181
|
+
const { redirectUri: redirectUri , state: state , codeVerifier: codeVerifier } = signInSession;
|
|
182
|
+
const code = (0, $ElS14$verifyAndParseCodeFromCallbackUri)(callbackUri, redirectUri, state);
|
|
183
|
+
const { appId: clientId } = logtoConfig;
|
|
184
|
+
const { tokenEndpoint: tokenEndpoint } = await this.getOidcConfig();
|
|
185
|
+
const codeTokenResponse = await (0, $ElS14$fetchTokenByAuthorizationCode)({
|
|
186
|
+
clientId: clientId,
|
|
187
|
+
tokenEndpoint: tokenEndpoint,
|
|
188
|
+
redirectUri: redirectUri,
|
|
189
|
+
codeVerifier: codeVerifier,
|
|
190
|
+
code: code
|
|
191
|
+
}, requester);
|
|
192
|
+
await this.verifyIdToken(codeTokenResponse.idToken);
|
|
193
|
+
this.saveCodeToken(codeTokenResponse);
|
|
194
|
+
this.signInSession = null;
|
|
195
|
+
}
|
|
196
|
+
async signOut(postLogoutRedirectUri) {
|
|
197
|
+
if (!this.idToken) throw new (0, $092943c955830b14$export$877962ca249b8fc8)("not_authenticated");
|
|
198
|
+
const { appId: clientId } = this.logtoConfig;
|
|
199
|
+
const { endSessionEndpoint: endSessionEndpoint , revocationEndpoint: revocationEndpoint } = await this.getOidcConfig();
|
|
200
|
+
if (this.refreshToken) try {
|
|
201
|
+
await (0, $ElS14$revoke)(revocationEndpoint, clientId, this.refreshToken, this.requester);
|
|
202
|
+
} catch {
|
|
203
|
+
// Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
|
|
204
|
+
}
|
|
205
|
+
const url = (0, $ElS14$generateSignOutUri)({
|
|
206
|
+
endSessionEndpoint: endSessionEndpoint,
|
|
207
|
+
postLogoutRedirectUri: postLogoutRedirectUri,
|
|
208
|
+
idToken: this.idToken
|
|
209
|
+
});
|
|
210
|
+
this.accessTokenMap.clear();
|
|
211
|
+
this.refreshToken = null;
|
|
212
|
+
this.idToken = null;
|
|
213
|
+
window.location.assign(url);
|
|
214
|
+
}
|
|
215
|
+
async getAccessTokenByRefreshToken(resource) {
|
|
216
|
+
if (!this.refreshToken) throw new (0, $092943c955830b14$export$877962ca249b8fc8)("not_authenticated");
|
|
217
|
+
try {
|
|
218
|
+
const accessTokenKey = (0, $2f0dba05fbbfeb85$export$8f595bd2a47bcea6)(resource);
|
|
219
|
+
const { appId: clientId } = this.logtoConfig;
|
|
220
|
+
const { tokenEndpoint: tokenEndpoint } = await this.getOidcConfig();
|
|
221
|
+
const { accessToken: accessToken , refreshToken: refreshToken , idToken: idToken , scope: scope , expiresIn: expiresIn } = await (0, $ElS14$fetchTokenByRefreshToken)({
|
|
222
|
+
clientId: clientId,
|
|
223
|
+
tokenEndpoint: tokenEndpoint,
|
|
224
|
+
refreshToken: this.refreshToken,
|
|
225
|
+
resource: resource,
|
|
226
|
+
scopes: resource ? [
|
|
227
|
+
"offline_access"
|
|
228
|
+
] : undefined
|
|
229
|
+
}, this.requester);
|
|
230
|
+
this.accessTokenMap.set(accessTokenKey, {
|
|
231
|
+
token: accessToken,
|
|
232
|
+
scope: scope,
|
|
233
|
+
expiresAt: Math.round(Date.now() / 1000) + expiresIn
|
|
234
|
+
});
|
|
235
|
+
this.refreshToken = refreshToken;
|
|
236
|
+
if (idToken) {
|
|
237
|
+
await this.verifyIdToken(idToken);
|
|
238
|
+
this.idToken = idToken;
|
|
239
|
+
}
|
|
240
|
+
return accessToken;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
throw new (0, $092943c955830b14$export$877962ca249b8fc8)("get_access_token_by_refresh_token_failed", error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async _getOidcConfig() {
|
|
246
|
+
const { endpoint: endpoint } = this.logtoConfig;
|
|
247
|
+
const discoveryEndpoint = (0, $2f0dba05fbbfeb85$export$5d9c34f69c80822b)(endpoint);
|
|
248
|
+
return (0, $ElS14$fetchOidcConfig)(discoveryEndpoint, this.requester);
|
|
249
|
+
}
|
|
250
|
+
async _getJwtVerifyGetKey() {
|
|
251
|
+
const { jwksUri: jwksUri } = await this.getOidcConfig();
|
|
252
|
+
return (0, $ElS14$createRemoteJWKSet)(new URL(jwksUri));
|
|
253
|
+
}
|
|
254
|
+
async verifyIdToken(idToken) {
|
|
255
|
+
const { appId: appId } = this.logtoConfig;
|
|
256
|
+
const { issuer: issuer } = await this.getOidcConfig();
|
|
257
|
+
const jwtVerifyGetKey = await this.getJwtVerifyGetKey();
|
|
258
|
+
try {
|
|
259
|
+
await (0, $ElS14$verifyIdToken)(idToken, appId, issuer, jwtVerifyGetKey);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
throw new (0, $092943c955830b14$export$877962ca249b8fc8)("invalid_id_token", error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
saveCodeToken({ refreshToken: refreshToken , idToken: idToken , scope: scope , accessToken: accessToken , expiresIn: expiresIn }) {
|
|
265
|
+
this.refreshToken = refreshToken ?? null;
|
|
266
|
+
this.idToken = idToken;
|
|
267
|
+
// NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
|
|
268
|
+
const accessTokenKey = (0, $2f0dba05fbbfeb85$export$8f595bd2a47bcea6)();
|
|
269
|
+
const expiresAt = Date.now() / 1000 + expiresIn;
|
|
270
|
+
this.accessTokenMap.set(accessTokenKey, {
|
|
271
|
+
token: accessToken,
|
|
272
|
+
scope: scope,
|
|
273
|
+
expiresAt: expiresAt
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
export {$90df2ab0e44b5eba$export$7b65a75f516b80e1 as LogtoSignInSessionItemSchema, $90df2ab0e44b5eba$export$2e2bcd8739ae039 as default, $90df2ab0e44b5eba$re_export$LogtoError as LogtoError, $90df2ab0e44b5eba$re_export$OidcError as OidcError, $90df2ab0e44b5eba$import$5548085c5b0a2ee3$83716a4aa1642908 as Prompt, $092943c955830b14$export$877962ca249b8fc8 as LogtoClientError};
|
|
280
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["packages/browser/src/index.ts","packages/browser/src/errors.ts","packages/browser/src/utils/index.ts"],"sourcesContent":["import {\n CodeTokenResponse,\n createRequester,\n decodeIdToken,\n fetchOidcConfig,\n fetchTokenByAuthorizationCode,\n fetchTokenByRefreshToken,\n generateCodeChallenge,\n generateCodeVerifier,\n generateSignInUri,\n generateSignOutUri,\n generateState,\n IdTokenClaims,\n Prompt,\n Requester,\n revoke,\n verifyAndParseCodeFromCallbackUri,\n verifyIdToken,\n withReservedScopes,\n} from '@logto/js';\nimport { Nullable } from '@silverhand/essentials';\nimport { createRemoteJWKSet } from 'jose';\nimport once from 'lodash.once';\nimport { assert, Infer, string, type } from 'superstruct';\n\nimport { LogtoClientError } from './errors';\nimport {\n buildAccessTokenKey,\n buildIdTokenKey,\n buildLogtoKey,\n buildRefreshTokenKey,\n getDiscoveryEndpoint,\n} from './utils';\n\nexport type { IdTokenClaims, LogtoErrorCode } from '@logto/js';\nexport { LogtoError, OidcError, Prompt } from '@logto/js';\nexport * from './errors';\n\nexport type LogtoConfig = {\n endpoint: string;\n appId: string;\n scopes?: string[];\n resources?: string[];\n prompt?: Prompt;\n usingPersistStorage?: boolean;\n};\n\nexport type AccessToken = {\n token: string;\n scope: string;\n expiresAt: number; // Unix Timestamp in seconds\n};\n\nexport const LogtoSignInSessionItemSchema = type({\n redirectUri: string(),\n codeVerifier: string(),\n state: string(),\n});\n\nexport type LogtoSignInSessionItem = Infer<typeof LogtoSignInSessionItemSchema>;\n\nexport default class LogtoClient {\n protected readonly logtoConfig: LogtoConfig;\n protected readonly getOidcConfig = once(this._getOidcConfig);\n protected readonly getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);\n\n protected readonly logtoStorageKey: string;\n protected readonly requester: Requester;\n\n protected readonly accessTokenMap = new Map<string, AccessToken>();\n\n private readonly getAccessTokenPromiseMap = new Map<string, Promise<string>>();\n private _idToken: Nullable<string>;\n\n constructor(logtoConfig: LogtoConfig, requester = createRequester()) {\n this.logtoConfig = {\n ...logtoConfig,\n prompt: logtoConfig.prompt ?? Prompt.Consent,\n scopes: withReservedScopes(logtoConfig.scopes).split(' '),\n };\n this.logtoStorageKey = buildLogtoKey(logtoConfig.appId);\n this.requester = requester;\n this._idToken = localStorage.getItem(buildIdTokenKey(this.logtoStorageKey));\n }\n\n public get isAuthenticated() {\n return Boolean(this.idToken);\n }\n\n protected get signInSession(): Nullable<LogtoSignInSessionItem> {\n const jsonItem = sessionStorage.getItem(this.logtoStorageKey);\n\n if (!jsonItem) {\n return null;\n }\n\n try {\n const item: unknown = JSON.parse(jsonItem);\n assert(item, LogtoSignInSessionItemSchema);\n\n return item;\n } catch (error: unknown) {\n throw new LogtoClientError('sign_in_session.invalid', error);\n }\n }\n\n protected set signInSession(logtoSignInSessionItem: Nullable<LogtoSignInSessionItem>) {\n if (!logtoSignInSessionItem) {\n sessionStorage.removeItem(this.logtoStorageKey);\n\n return;\n }\n\n const jsonItem = JSON.stringify(logtoSignInSessionItem);\n sessionStorage.setItem(this.logtoStorageKey, jsonItem);\n }\n\n get refreshToken() {\n return localStorage.getItem(buildRefreshTokenKey(this.logtoStorageKey));\n }\n\n private set refreshToken(refreshToken: Nullable<string>) {\n const refreshTokenKey = buildRefreshTokenKey(this.logtoStorageKey);\n\n if (!refreshToken) {\n localStorage.removeItem(refreshTokenKey);\n\n return;\n }\n\n localStorage.setItem(refreshTokenKey, refreshToken);\n }\n\n get idToken() {\n return this._idToken;\n }\n\n private set idToken(idToken: Nullable<string>) {\n this._idToken = idToken;\n\n const idTokenKey = buildIdTokenKey(this.logtoStorageKey);\n\n if (!idToken) {\n localStorage.removeItem(idTokenKey);\n\n return;\n }\n\n localStorage.setItem(idTokenKey, idToken);\n }\n\n // eslint-disable-next-line complexity\n public async getAccessToken(resource?: string): Promise<string> {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const accessTokenKey = buildAccessTokenKey(resource);\n const accessToken = this.accessTokenMap.get(accessTokenKey);\n\n if (accessToken && accessToken.expiresAt > Date.now() / 1000) {\n return accessToken.token;\n }\n\n // Since the access token has expired, delete it from the map.\n if (accessToken) {\n this.accessTokenMap.delete(accessTokenKey);\n }\n\n /**\n * Need to fetch a new access token using refresh token.\n * Reuse the cached promise if exists.\n */\n const cachedPromise = this.getAccessTokenPromiseMap.get(accessTokenKey);\n\n if (cachedPromise) {\n return cachedPromise;\n }\n\n /**\n * Create a new promise and cache in map to avoid race condition.\n * Since we enable \"refresh token rotation\" by default,\n * it will be problematic when calling multiple `getAccessToken()` closely.\n */\n const promise = this.getAccessTokenByRefreshToken(resource);\n this.getAccessTokenPromiseMap.set(accessTokenKey, promise);\n\n const token = await promise;\n this.getAccessTokenPromiseMap.delete(accessTokenKey);\n\n return token;\n }\n\n public getIdTokenClaims(): IdTokenClaims {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n return decodeIdToken(this.idToken);\n }\n\n public async signIn(redirectUri: string) {\n const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;\n const { authorizationEndpoint } = await this.getOidcConfig();\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n const signInUri = generateSignInUri({\n authorizationEndpoint,\n clientId,\n redirectUri,\n codeChallenge,\n state,\n scopes,\n resources,\n prompt,\n });\n\n this.signInSession = { redirectUri, codeVerifier, state };\n this.refreshToken = null;\n this.idToken = null;\n\n window.location.assign(signInUri);\n }\n\n public isSignInRedirected(url: string): boolean {\n const { signInSession } = this;\n\n if (!signInSession) {\n return false;\n }\n const { redirectUri } = signInSession;\n const { origin, pathname } = new URL(url);\n\n return `${origin}${pathname}` === redirectUri;\n }\n\n public async handleSignInCallback(callbackUri: string) {\n const { signInSession, logtoConfig, requester } = this;\n\n if (!signInSession) {\n throw new LogtoClientError('sign_in_session.not_found');\n }\n\n const { redirectUri, state, codeVerifier } = signInSession;\n const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);\n\n const { appId: clientId } = logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const codeTokenResponse = await fetchTokenByAuthorizationCode(\n {\n clientId,\n tokenEndpoint,\n redirectUri,\n codeVerifier,\n code,\n },\n requester\n );\n\n await this.verifyIdToken(codeTokenResponse.idToken);\n\n this.saveCodeToken(codeTokenResponse);\n this.signInSession = null;\n }\n\n public async signOut(postLogoutRedirectUri?: string) {\n if (!this.idToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n const { appId: clientId } = this.logtoConfig;\n const { endSessionEndpoint, revocationEndpoint } = await this.getOidcConfig();\n\n if (this.refreshToken) {\n try {\n await revoke(revocationEndpoint, clientId, this.refreshToken, this.requester);\n } catch {\n // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed\n }\n }\n\n const url = generateSignOutUri({\n endSessionEndpoint,\n postLogoutRedirectUri,\n idToken: this.idToken,\n });\n\n this.accessTokenMap.clear();\n this.refreshToken = null;\n this.idToken = null;\n\n window.location.assign(url);\n }\n\n private async getAccessTokenByRefreshToken(resource?: string): Promise<string> {\n if (!this.refreshToken) {\n throw new LogtoClientError('not_authenticated');\n }\n\n try {\n const accessTokenKey = buildAccessTokenKey(resource);\n const { appId: clientId } = this.logtoConfig;\n const { tokenEndpoint } = await this.getOidcConfig();\n const { accessToken, refreshToken, idToken, scope, expiresIn } =\n await fetchTokenByRefreshToken(\n {\n clientId,\n tokenEndpoint,\n refreshToken: this.refreshToken,\n resource,\n scopes: resource ? ['offline_access'] : undefined, // Force remove openid scope from the request\n },\n this.requester\n );\n\n this.accessTokenMap.set(accessTokenKey, {\n token: accessToken,\n scope,\n expiresAt: Math.round(Date.now() / 1000) + expiresIn,\n });\n\n this.refreshToken = refreshToken;\n\n if (idToken) {\n await this.verifyIdToken(idToken);\n this.idToken = idToken;\n }\n\n return accessToken;\n } catch (error: unknown) {\n throw new LogtoClientError('get_access_token_by_refresh_token_failed', error);\n }\n }\n\n private async _getOidcConfig() {\n const { endpoint } = this.logtoConfig;\n const discoveryEndpoint = getDiscoveryEndpoint(endpoint);\n\n return fetchOidcConfig(discoveryEndpoint, this.requester);\n }\n\n private async _getJwtVerifyGetKey() {\n const { jwksUri } = await this.getOidcConfig();\n\n return createRemoteJWKSet(new URL(jwksUri));\n }\n\n private async verifyIdToken(idToken: string) {\n const { appId } = this.logtoConfig;\n const { issuer } = await this.getOidcConfig();\n const jwtVerifyGetKey = await this.getJwtVerifyGetKey();\n\n try {\n await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);\n } catch (error: unknown) {\n throw new LogtoClientError('invalid_id_token', error);\n }\n }\n\n private saveCodeToken({\n refreshToken,\n idToken,\n scope,\n accessToken,\n expiresIn,\n }: CodeTokenResponse) {\n this.refreshToken = refreshToken ?? null;\n this.idToken = idToken;\n\n // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)\n const accessTokenKey = buildAccessTokenKey();\n const expiresAt = Date.now() / 1000 + expiresIn;\n this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });\n }\n}\n","import { NormalizeKeyPaths } from '@silverhand/essentials';\nimport get from 'lodash.get';\n\nconst logtoClientErrorCodes = Object.freeze({\n sign_in_session: {\n invalid: 'Invalid sign-in session.',\n not_found: 'Sign-in session not found.',\n },\n not_authenticated: 'Not authenticated.',\n get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',\n invalid_id_token: 'Invalid id token.',\n});\n\nexport type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;\n\nconst getMessageByErrorCode = (errorCode: LogtoClientErrorCode): string => {\n // TODO: linear issue LOG-1419\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 { discoveryPath } from '@logto/js';\n\nconst logtoStorageItemKeyPrefix = `logto`;\nexport const buildLogtoKey = (key: string): string => `${logtoStorageItemKeyPrefix}:${key}`;\nexport const buildRefreshTokenKey = (logtoKey: string) => `${logtoKey}:refreshToken`;\nexport const buildIdTokenKey = (logtoKey: string) => `${logtoKey}:idToken`;\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"],"names":[],"version":3,"file":"module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logto/browser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-alpha.0",
|
|
4
|
+
"source": "./src/index.ts",
|
|
4
5
|
"main": "./lib/index.js",
|
|
5
|
-
"exports":
|
|
6
|
-
|
|
6
|
+
"exports": {
|
|
7
|
+
"require": "./lib/index.js",
|
|
8
|
+
"import": "./lib/module.js"
|
|
9
|
+
},
|
|
10
|
+
"module": "./lib/module.js",
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
7
12
|
"files": [
|
|
8
13
|
"lib"
|
|
9
14
|
],
|
|
@@ -16,14 +21,15 @@
|
|
|
16
21
|
"scripts": {
|
|
17
22
|
"dev:tsc": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
|
|
18
23
|
"precommit": "lint-staged",
|
|
19
|
-
"
|
|
24
|
+
"check": "tsc --noEmit",
|
|
25
|
+
"build": "rm -rf lib/ && pnpm check && parcel build",
|
|
20
26
|
"lint": "eslint --ext .ts src",
|
|
21
27
|
"test": "jest",
|
|
22
28
|
"test:coverage": "jest --silent --coverage",
|
|
23
29
|
"prepack": "pnpm test"
|
|
24
30
|
},
|
|
25
31
|
"dependencies": {
|
|
26
|
-
"@logto/js": "^0.
|
|
32
|
+
"@logto/js": "^1.0.0-alpha.0",
|
|
27
33
|
"@silverhand/essentials": "^1.1.6",
|
|
28
34
|
"jose": "^4.5.0",
|
|
29
35
|
"lodash.get": "^4.4.2",
|
|
@@ -32,6 +38,9 @@
|
|
|
32
38
|
},
|
|
33
39
|
"devDependencies": {
|
|
34
40
|
"@jest/types": "^27.5.1",
|
|
41
|
+
"@parcel/core": "^2.6.2",
|
|
42
|
+
"@parcel/packager-ts": "^2.6.2",
|
|
43
|
+
"@parcel/transformer-typescript-types": "^2.6.2",
|
|
35
44
|
"@silverhand/eslint-config": "^0.14.0",
|
|
36
45
|
"@silverhand/ts-config": "^0.14.0",
|
|
37
46
|
"@types/jest": "^27.4.0",
|
|
@@ -42,6 +51,7 @@
|
|
|
42
51
|
"jest-location-mock": "^1.0.9",
|
|
43
52
|
"jest-matcher-specific-error": "^1.0.0",
|
|
44
53
|
"lint-staged": "^13.0.0",
|
|
54
|
+
"parcel": "^2.6.2",
|
|
45
55
|
"prettier": "^2.3.2",
|
|
46
56
|
"text-encoder": "^0.0.4",
|
|
47
57
|
"ts-jest": "^27.0.4",
|
|
@@ -54,5 +64,5 @@
|
|
|
54
64
|
"publishConfig": {
|
|
55
65
|
"access": "public"
|
|
56
66
|
},
|
|
57
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "e7bebf027d400960ac6ef1d63ed84656aa6d1c62"
|
|
58
68
|
}
|
package/lib/errors.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { NormalizeKeyPaths } from '@silverhand/essentials';
|
|
2
|
-
declare const logtoClientErrorCodes: Readonly<{
|
|
3
|
-
sign_in_session: {
|
|
4
|
-
invalid: string;
|
|
5
|
-
not_found: string;
|
|
6
|
-
};
|
|
7
|
-
not_authenticated: string;
|
|
8
|
-
get_access_token_by_refresh_token_failed: string;
|
|
9
|
-
invalid_id_token: string;
|
|
10
|
-
}>;
|
|
11
|
-
export declare type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;
|
|
12
|
-
export declare class LogtoClientError extends Error {
|
|
13
|
-
code: LogtoClientErrorCode;
|
|
14
|
-
data: unknown;
|
|
15
|
-
constructor(code: LogtoClientErrorCode, data?: unknown);
|
|
16
|
-
}
|
|
17
|
-
export {};
|
package/lib/errors.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.LogtoClientError = void 0;
|
|
7
|
-
const lodash_get_1 = __importDefault(require("lodash.get"));
|
|
8
|
-
const logtoClientErrorCodes = Object.freeze({
|
|
9
|
-
sign_in_session: {
|
|
10
|
-
invalid: 'Invalid sign-in session.',
|
|
11
|
-
not_found: 'Sign-in session not found.',
|
|
12
|
-
},
|
|
13
|
-
not_authenticated: 'Not authenticated.',
|
|
14
|
-
get_access_token_by_refresh_token_failed: 'Failed to get access token by refresh token.',
|
|
15
|
-
invalid_id_token: 'Invalid id token.',
|
|
16
|
-
});
|
|
17
|
-
const getMessageByErrorCode = (errorCode) => {
|
|
18
|
-
// TODO: linear issue LOG-1419
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
20
|
-
const message = (0, lodash_get_1.default)(logtoClientErrorCodes, errorCode);
|
|
21
|
-
if (typeof message === 'string') {
|
|
22
|
-
return message;
|
|
23
|
-
}
|
|
24
|
-
return errorCode;
|
|
25
|
-
};
|
|
26
|
-
class LogtoClientError extends Error {
|
|
27
|
-
constructor(code, data) {
|
|
28
|
-
super(getMessageByErrorCode(code));
|
|
29
|
-
this.code = code;
|
|
30
|
-
this.data = data;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.LogtoClientError = LogtoClientError;
|
package/lib/utils/index.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare const buildLogtoKey: (key: string) => string;
|
|
2
|
-
export declare const buildRefreshTokenKey: (logtoKey: string) => string;
|
|
3
|
-
export declare const buildIdTokenKey: (logtoKey: string) => string;
|
|
4
|
-
export declare const buildAccessTokenKey: (resource?: string, scopes?: string[]) => string;
|
|
5
|
-
export declare const getDiscoveryEndpoint: (endpoint: string) => string;
|
package/lib/utils/index.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDiscoveryEndpoint = exports.buildAccessTokenKey = exports.buildIdTokenKey = exports.buildRefreshTokenKey = exports.buildLogtoKey = void 0;
|
|
4
|
-
const js_1 = require("@logto/js");
|
|
5
|
-
const logtoStorageItemKeyPrefix = `logto`;
|
|
6
|
-
const buildLogtoKey = (key) => `${logtoStorageItemKeyPrefix}:${key}`;
|
|
7
|
-
exports.buildLogtoKey = buildLogtoKey;
|
|
8
|
-
const buildRefreshTokenKey = (logtoKey) => `${logtoKey}:refreshToken`;
|
|
9
|
-
exports.buildRefreshTokenKey = buildRefreshTokenKey;
|
|
10
|
-
const buildIdTokenKey = (logtoKey) => `${logtoKey}:idToken`;
|
|
11
|
-
exports.buildIdTokenKey = buildIdTokenKey;
|
|
12
|
-
const buildAccessTokenKey = (resource = '', scopes = []) => `${scopes.slice().sort().join(' ')}@${resource}`;
|
|
13
|
-
exports.buildAccessTokenKey = buildAccessTokenKey;
|
|
14
|
-
const getDiscoveryEndpoint = (endpoint) => new URL(js_1.discoveryPath, endpoint).toString();
|
|
15
|
-
exports.getDiscoveryEndpoint = getDiscoveryEndpoint;
|