@logto/client 2.4.0 → 2.5.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/adapter/types.d.ts +5 -4
- package/lib/client.cjs +14 -20
- package/lib/client.d.ts +25 -7
- package/lib/client.js +14 -20
- package/lib/types/index.d.ts +1 -0
- package/package.json +1 -1
package/lib/adapter/types.d.ts
CHANGED
|
@@ -39,16 +39,17 @@ export type InferStorageKey<S> = S extends Storage<infer Key> ? Key : never;
|
|
|
39
39
|
* @param url The URL to navigate to.
|
|
40
40
|
* @param parameters The parameters for the navigation.
|
|
41
41
|
* @param parameters.redirectUri The redirect URI that the user will be redirected to after the
|
|
42
|
-
* flow is completed. That is, the "redirect URI" for sign-in and "post-logout redirect URI" for
|
|
43
|
-
* sign-out.
|
|
44
|
-
* @param parameters.for The purpose of the navigation. It can be either "sign-in"
|
|
42
|
+
* flow is completed. That is, the "redirect URI" for "sign-in" and "post-logout redirect URI" for
|
|
43
|
+
* "sign-out". For the "post-sign-in" navigation, it should be ignored.
|
|
44
|
+
* @param parameters.for The purpose of the navigation. It can be either "sign-in", "sign-out", or
|
|
45
|
+
* "post-sign-in".
|
|
45
46
|
* @remarks Usually, the `redirectUri` parameter can be ignored unless the client needs to pass the
|
|
46
47
|
* redirect scheme or other parameters to the native app, such as `ASWebAuthenticationSession` in
|
|
47
48
|
* iOS.
|
|
48
49
|
*/
|
|
49
50
|
export type Navigate = (url: string, parameters: {
|
|
50
51
|
redirectUri?: string;
|
|
51
|
-
for: 'sign-in' | 'sign-out';
|
|
52
|
+
for: 'sign-in' | 'sign-out' | 'post-sign-in';
|
|
52
53
|
}) => void | Promise<void>;
|
|
53
54
|
export type JwtVerifier = {
|
|
54
55
|
verifyIdToken(idToken: string): Promise<void>;
|
package/lib/client.cjs
CHANGED
|
@@ -9,6 +9,7 @@ var memoize = require('./utils/memoize.cjs');
|
|
|
9
9
|
var once = require('./utils/once.cjs');
|
|
10
10
|
var types = require('./adapter/types.cjs');
|
|
11
11
|
|
|
12
|
+
/* eslint-disable max-lines */
|
|
12
13
|
/**
|
|
13
14
|
* The Logto base client class that provides the essential methods for
|
|
14
15
|
* interacting with the Logto server.
|
|
@@ -139,23 +140,12 @@ class StandardLogtoClient {
|
|
|
139
140
|
}
|
|
140
141
|
return js.fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
|
|
141
142
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
* To fetch the tokens from the authorization code, use {@link handleSignInCallback}
|
|
149
|
-
* after the user is redirected in the callback URI.
|
|
150
|
-
*
|
|
151
|
-
* @param redirectUri The redirect URI that the user will be redirected to after the sign-in flow is completed.
|
|
152
|
-
* @param interactionMode The interaction mode to be used for the authorization request. Note it's not
|
|
153
|
-
* a part of the OIDC standard, but a Logto-specific extension. Defaults to `signIn`.
|
|
154
|
-
*
|
|
155
|
-
* @see {@link https://docs.logto.io/docs/recipes/integrate-logto/vanilla-js/#sign-in | Sign in} for more information.
|
|
156
|
-
* @see {@link InteractionMode}
|
|
157
|
-
*/
|
|
158
|
-
async signIn(redirectUri, interactionMode) {
|
|
143
|
+
async signIn(options, mode) {
|
|
144
|
+
const { redirectUri: redirectUriUrl, postRedirectUri: postRedirectUriUrl, interactionMode, } = typeof options === 'string' || options instanceof URL
|
|
145
|
+
? { redirectUri: options, postRedirectUri: undefined, interactionMode: mode }
|
|
146
|
+
: options;
|
|
147
|
+
const redirectUri = redirectUriUrl.toString();
|
|
148
|
+
const postRedirectUri = postRedirectUriUrl?.toString();
|
|
159
149
|
const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;
|
|
160
150
|
const { authorizationEndpoint } = await this.getOidcConfig();
|
|
161
151
|
const [codeVerifier, state] = await Promise.all([
|
|
@@ -166,7 +156,7 @@ class StandardLogtoClient {
|
|
|
166
156
|
const signInUri = js.generateSignInUri({
|
|
167
157
|
authorizationEndpoint,
|
|
168
158
|
clientId,
|
|
169
|
-
redirectUri,
|
|
159
|
+
redirectUri: redirectUri.toString(),
|
|
170
160
|
codeChallenge,
|
|
171
161
|
state,
|
|
172
162
|
scopes,
|
|
@@ -175,7 +165,7 @@ class StandardLogtoClient {
|
|
|
175
165
|
interactionMode,
|
|
176
166
|
});
|
|
177
167
|
await Promise.all([
|
|
178
|
-
this.setSignInSession({ redirectUri, codeVerifier, state }),
|
|
168
|
+
this.setSignInSession({ redirectUri, postRedirectUri, codeVerifier, state }),
|
|
179
169
|
this.setRefreshToken(null),
|
|
180
170
|
this.setIdToken(null),
|
|
181
171
|
]);
|
|
@@ -349,7 +339,7 @@ class StandardLogtoClient {
|
|
|
349
339
|
if (!signInSession) {
|
|
350
340
|
throw new errors.LogtoClientError('sign_in_session.not_found');
|
|
351
341
|
}
|
|
352
|
-
const { redirectUri, state, codeVerifier } = signInSession;
|
|
342
|
+
const { redirectUri, postRedirectUri, state, codeVerifier } = signInSession;
|
|
353
343
|
const code = js.verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
|
|
354
344
|
// NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
|
|
355
345
|
const accessTokenKey = index$2.buildAccessTokenKey();
|
|
@@ -377,7 +367,11 @@ class StandardLogtoClient {
|
|
|
377
367
|
});
|
|
378
368
|
await this.saveAccessTokenMap();
|
|
379
369
|
await this.setSignInSession(null);
|
|
370
|
+
if (postRedirectUri) {
|
|
371
|
+
await this.adapter.navigate(postRedirectUri, { for: 'post-sign-in' });
|
|
372
|
+
}
|
|
380
373
|
}
|
|
381
374
|
}
|
|
375
|
+
/* eslint-enable max-lines */
|
|
382
376
|
|
|
383
377
|
exports.StandardLogtoClient = StandardLogtoClient;
|
package/lib/client.d.ts
CHANGED
|
@@ -2,6 +2,27 @@ import { type IdTokenClaims, type UserInfoResponse, type InteractionMode, type A
|
|
|
2
2
|
import { type Nullable } from '@silverhand/essentials';
|
|
3
3
|
import { ClientAdapterInstance, type ClientAdapter, type JwtVerifier } from './adapter/index.js';
|
|
4
4
|
import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './types/index.js';
|
|
5
|
+
export type SignInOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* The redirect URI that the user will be redirected to after the sign-in flow is completed.
|
|
8
|
+
*/
|
|
9
|
+
redirectUri: string | URL;
|
|
10
|
+
/**
|
|
11
|
+
* The URI that the user will be redirected to after `redirectUri` successfully handled the
|
|
12
|
+
* sign-in callback. If not specified, the user will stay on the `redirectUri` page.
|
|
13
|
+
*/
|
|
14
|
+
postRedirectUri?: string | URL;
|
|
15
|
+
/**
|
|
16
|
+
* The interaction mode to be used for the authorization request. It determines the first page
|
|
17
|
+
* that the user will see in the sign-in flow.
|
|
18
|
+
*
|
|
19
|
+
* Note it's not a part of the OIDC standard, but a Logto-specific extension.
|
|
20
|
+
*
|
|
21
|
+
* @default InteractionMode.SignIn
|
|
22
|
+
* @see {@link InteractionMode}
|
|
23
|
+
*/
|
|
24
|
+
interactionMode?: InteractionMode;
|
|
25
|
+
};
|
|
5
26
|
/**
|
|
6
27
|
* The Logto base client class that provides the essential methods for
|
|
7
28
|
* interacting with the Logto server.
|
|
@@ -106,6 +127,7 @@ export declare class StandardLogtoClient {
|
|
|
106
127
|
* @throws LogtoClientError if the user is not authenticated.
|
|
107
128
|
*/
|
|
108
129
|
fetchUserInfo(): Promise<UserInfoResponse>;
|
|
130
|
+
signIn(options: SignInOptions): Promise<void>;
|
|
109
131
|
/**
|
|
110
132
|
* Start the sign-in flow with the specified redirect URI. The URI must be
|
|
111
133
|
* registered in the Logto Console.
|
|
@@ -115,14 +137,10 @@ export declare class StandardLogtoClient {
|
|
|
115
137
|
* To fetch the tokens from the authorization code, use {@link handleSignInCallback}
|
|
116
138
|
* after the user is redirected in the callback URI.
|
|
117
139
|
*
|
|
118
|
-
* @param redirectUri
|
|
119
|
-
* @param interactionMode
|
|
120
|
-
* a part of the OIDC standard, but a Logto-specific extension. Defaults to `signIn`.
|
|
121
|
-
*
|
|
122
|
-
* @see {@link https://docs.logto.io/docs/recipes/integrate-logto/vanilla-js/#sign-in | Sign in} for more information.
|
|
123
|
-
* @see {@link InteractionMode}
|
|
140
|
+
* @param redirectUri See {@link SignInOptions.redirectUri}.
|
|
141
|
+
* @param interactionMode See {@link SignInOptions.interactionMode}.
|
|
124
142
|
*/
|
|
125
|
-
signIn(redirectUri:
|
|
143
|
+
signIn(redirectUri: SignInOptions['redirectUri'], interactionMode?: SignInOptions['interactionMode']): Promise<void>;
|
|
126
144
|
/**
|
|
127
145
|
* Check if the user is redirected from the sign-in page by checking if the
|
|
128
146
|
* current URL matches the redirect URI in the sign-in session.
|
package/lib/client.js
CHANGED
|
@@ -7,6 +7,7 @@ import { memoize } from './utils/memoize.js';
|
|
|
7
7
|
import { once } from './utils/once.js';
|
|
8
8
|
import { PersistKey, CacheKey } from './adapter/types.js';
|
|
9
9
|
|
|
10
|
+
/* eslint-disable max-lines */
|
|
10
11
|
/**
|
|
11
12
|
* The Logto base client class that provides the essential methods for
|
|
12
13
|
* interacting with the Logto server.
|
|
@@ -137,23 +138,12 @@ class StandardLogtoClient {
|
|
|
137
138
|
}
|
|
138
139
|
return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
* To fetch the tokens from the authorization code, use {@link handleSignInCallback}
|
|
147
|
-
* after the user is redirected in the callback URI.
|
|
148
|
-
*
|
|
149
|
-
* @param redirectUri The redirect URI that the user will be redirected to after the sign-in flow is completed.
|
|
150
|
-
* @param interactionMode The interaction mode to be used for the authorization request. Note it's not
|
|
151
|
-
* a part of the OIDC standard, but a Logto-specific extension. Defaults to `signIn`.
|
|
152
|
-
*
|
|
153
|
-
* @see {@link https://docs.logto.io/docs/recipes/integrate-logto/vanilla-js/#sign-in | Sign in} for more information.
|
|
154
|
-
* @see {@link InteractionMode}
|
|
155
|
-
*/
|
|
156
|
-
async signIn(redirectUri, interactionMode) {
|
|
141
|
+
async signIn(options, mode) {
|
|
142
|
+
const { redirectUri: redirectUriUrl, postRedirectUri: postRedirectUriUrl, interactionMode, } = typeof options === 'string' || options instanceof URL
|
|
143
|
+
? { redirectUri: options, postRedirectUri: undefined, interactionMode: mode }
|
|
144
|
+
: options;
|
|
145
|
+
const redirectUri = redirectUriUrl.toString();
|
|
146
|
+
const postRedirectUri = postRedirectUriUrl?.toString();
|
|
157
147
|
const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;
|
|
158
148
|
const { authorizationEndpoint } = await this.getOidcConfig();
|
|
159
149
|
const [codeVerifier, state] = await Promise.all([
|
|
@@ -164,7 +154,7 @@ class StandardLogtoClient {
|
|
|
164
154
|
const signInUri = generateSignInUri({
|
|
165
155
|
authorizationEndpoint,
|
|
166
156
|
clientId,
|
|
167
|
-
redirectUri,
|
|
157
|
+
redirectUri: redirectUri.toString(),
|
|
168
158
|
codeChallenge,
|
|
169
159
|
state,
|
|
170
160
|
scopes,
|
|
@@ -173,7 +163,7 @@ class StandardLogtoClient {
|
|
|
173
163
|
interactionMode,
|
|
174
164
|
});
|
|
175
165
|
await Promise.all([
|
|
176
|
-
this.setSignInSession({ redirectUri, codeVerifier, state }),
|
|
166
|
+
this.setSignInSession({ redirectUri, postRedirectUri, codeVerifier, state }),
|
|
177
167
|
this.setRefreshToken(null),
|
|
178
168
|
this.setIdToken(null),
|
|
179
169
|
]);
|
|
@@ -347,7 +337,7 @@ class StandardLogtoClient {
|
|
|
347
337
|
if (!signInSession) {
|
|
348
338
|
throw new LogtoClientError('sign_in_session.not_found');
|
|
349
339
|
}
|
|
350
|
-
const { redirectUri, state, codeVerifier } = signInSession;
|
|
340
|
+
const { redirectUri, postRedirectUri, state, codeVerifier } = signInSession;
|
|
351
341
|
const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
|
|
352
342
|
// NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
|
|
353
343
|
const accessTokenKey = buildAccessTokenKey();
|
|
@@ -375,7 +365,11 @@ class StandardLogtoClient {
|
|
|
375
365
|
});
|
|
376
366
|
await this.saveAccessTokenMap();
|
|
377
367
|
await this.setSignInSession(null);
|
|
368
|
+
if (postRedirectUri) {
|
|
369
|
+
await this.adapter.navigate(postRedirectUri, { for: 'post-sign-in' });
|
|
370
|
+
}
|
|
378
371
|
}
|
|
379
372
|
}
|
|
373
|
+
/* eslint-enable max-lines */
|
|
380
374
|
|
|
381
375
|
export { StandardLogtoClient };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export declare const isLogtoSignInSessionItem: (data: unknown) => data is LogtoS
|
|
|
62
62
|
export declare const isLogtoAccessTokenMap: (data: unknown) => data is Record<string, AccessToken>;
|
|
63
63
|
export type LogtoSignInSessionItem = {
|
|
64
64
|
redirectUri: string;
|
|
65
|
+
postRedirectUri?: string;
|
|
65
66
|
codeVerifier: string;
|
|
66
67
|
state: string;
|
|
67
68
|
};
|