@jetbrains/ring-ui 7.0.94 → 7.0.95
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.
|
@@ -80,6 +80,7 @@ export interface AuthConfig extends TokenValidatorConfig {
|
|
|
80
80
|
translations?: AuthTranslations | null | undefined;
|
|
81
81
|
userParams?: RequestParams | undefined;
|
|
82
82
|
waitForRedirectTimeout: number;
|
|
83
|
+
rpInitiatedLogout: boolean;
|
|
83
84
|
}
|
|
84
85
|
type AuthPayloadMap = {
|
|
85
86
|
userChange: [AuthUser | undefined | void, void];
|
|
@@ -120,6 +121,7 @@ declare class Auth implements HTTPAuth {
|
|
|
120
121
|
static DEFAULT_CONFIG: Omit<AuthConfig, "serverUri">;
|
|
121
122
|
static API_PATH: string;
|
|
122
123
|
static API_AUTH_PATH: string;
|
|
124
|
+
static API_LOGOUT_PATH: string;
|
|
123
125
|
static API_PROFILE_PATH: string;
|
|
124
126
|
static CLOSE_BACKEND_DOWN_MESSAGE: string;
|
|
125
127
|
static CLOSE_WINDOW_MESSAGE: string;
|
|
@@ -187,7 +189,10 @@ declare class Auth implements HTTPAuth {
|
|
|
187
189
|
private _extractErrorMessage;
|
|
188
190
|
private _showBackendDownDialog;
|
|
189
191
|
/**
|
|
190
|
-
* Wipe accessToken and redirect to
|
|
192
|
+
* Wipe accessToken and redirect to logout endpoint.
|
|
193
|
+
* Uses RP-initiated logout flow (oauth2/logout) when rpInitiatedLogout config is enabled,
|
|
194
|
+
* falls back to oauth2/auth redirect otherwise.
|
|
195
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
191
196
|
*/
|
|
192
197
|
logout(extraParams?: Record<string, unknown>): Promise<void>;
|
|
193
198
|
private _runEmbeddedLogin;
|
|
@@ -43,12 +43,14 @@ const DEFAULT_CONFIG = {
|
|
|
43
43
|
onBackendDown: () => () => { },
|
|
44
44
|
defaultExpiresIn: DEFAULT_EXPIRES_TIMEOUT,
|
|
45
45
|
waitForRedirectTimeout: DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT,
|
|
46
|
+
rpInitiatedLogout: true,
|
|
46
47
|
translations: null,
|
|
47
48
|
};
|
|
48
49
|
class Auth {
|
|
49
50
|
static DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
50
51
|
static API_PATH = 'api/rest/';
|
|
51
52
|
static API_AUTH_PATH = 'oauth2/auth';
|
|
53
|
+
static API_LOGOUT_PATH = 'oauth2/logout';
|
|
52
54
|
static API_PROFILE_PATH = 'users/me';
|
|
53
55
|
static CLOSE_BACKEND_DOWN_MESSAGE = 'backend-check-succeeded';
|
|
54
56
|
static CLOSE_WINDOW_MESSAGE = 'close-login-window';
|
|
@@ -106,6 +108,7 @@ class Auth {
|
|
|
106
108
|
this._domainStorage = new AuthStorage({ messagePrefix: 'domain-message-' });
|
|
107
109
|
this._requestBuilder = new AuthRequestBuilder({
|
|
108
110
|
authorization: this.config.serverUri + Auth.API_PATH + Auth.API_AUTH_PATH,
|
|
111
|
+
logout: this.config.serverUri + Auth.API_PATH + Auth.API_LOGOUT_PATH,
|
|
109
112
|
clientId,
|
|
110
113
|
redirect,
|
|
111
114
|
redirectUri,
|
|
@@ -633,20 +636,24 @@ class Auth {
|
|
|
633
636
|
});
|
|
634
637
|
}
|
|
635
638
|
/**
|
|
636
|
-
* Wipe accessToken and redirect to
|
|
639
|
+
* Wipe accessToken and redirect to logout endpoint.
|
|
640
|
+
* Uses RP-initiated logout flow (oauth2/logout) when rpInitiatedLogout config is enabled,
|
|
641
|
+
* falls back to oauth2/auth redirect otherwise.
|
|
642
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
637
643
|
*/
|
|
638
644
|
async logout(extraParams) {
|
|
639
|
-
const requestParams = {
|
|
640
|
-
request_credentials: 'required',
|
|
641
|
-
...extraParams,
|
|
642
|
-
};
|
|
643
645
|
await this._checkBackendsStatusesIfEnabled();
|
|
644
646
|
await this.listeners.trigger('logout');
|
|
645
647
|
this._updateDomainUser(null);
|
|
646
648
|
await this._storage?.wipeToken();
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
this.
|
|
649
|
+
const request = this.config.rpInitiatedLogout
|
|
650
|
+
? await this._requestBuilder?.prepareLogoutRequest(extraParams)
|
|
651
|
+
: await this._requestBuilder?.prepareAuthRequest({
|
|
652
|
+
request_credentials: 'required',
|
|
653
|
+
...extraParams,
|
|
654
|
+
});
|
|
655
|
+
if (request) {
|
|
656
|
+
this._redirectCurrentPage(request.url);
|
|
650
657
|
}
|
|
651
658
|
}
|
|
652
659
|
async _runEmbeddedLogin() {
|
|
@@ -3,6 +3,7 @@ import type { AuthState } from './storage';
|
|
|
3
3
|
import type AuthStorage from './storage';
|
|
4
4
|
export interface AuthRequestBuilderConfig {
|
|
5
5
|
authorization: string;
|
|
6
|
+
logout?: string | null | undefined;
|
|
6
7
|
redirectUri?: string | null | undefined;
|
|
7
8
|
requestCredentials?: string | null | undefined;
|
|
8
9
|
clientId?: string | null | undefined;
|
|
@@ -38,6 +39,17 @@ export default class AuthRequestBuilder {
|
|
|
38
39
|
url: string;
|
|
39
40
|
stateId: string;
|
|
40
41
|
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Build a logout URL for RP-initiated logout flow.
|
|
44
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
45
|
+
*
|
|
46
|
+
* @param {object=} extraParams additional query parameters for logout request
|
|
47
|
+
* @return {Promise.<{url: string, stateId: string}>} logout URL with required parameters
|
|
48
|
+
*/
|
|
49
|
+
prepareLogoutRequest(extraParams?: Record<string, unknown> | null | undefined): Promise<{
|
|
50
|
+
url: string;
|
|
51
|
+
stateId: string;
|
|
52
|
+
}>;
|
|
41
53
|
/**
|
|
42
54
|
* @param {string} id
|
|
43
55
|
* @param {StoredState} storedState
|
|
@@ -51,6 +51,33 @@ export default class AuthRequestBuilder {
|
|
|
51
51
|
stateId,
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a logout URL for RP-initiated logout flow.
|
|
56
|
+
* See: https://youtrack.jetbrains.com/projects/HUB/articles/HUB-A-43#rp-initiated-logout
|
|
57
|
+
*
|
|
58
|
+
* @param {object=} extraParams additional query parameters for logout request
|
|
59
|
+
* @return {Promise.<{url: string, stateId: string}>} logout URL with required parameters
|
|
60
|
+
*/
|
|
61
|
+
async prepareLogoutRequest(extraParams) {
|
|
62
|
+
if (!this.config.logout) {
|
|
63
|
+
throw new Error('Logout URL is not configured');
|
|
64
|
+
}
|
|
65
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
66
|
+
const stateId = AuthRequestBuilder._uuid();
|
|
67
|
+
const logoutParams = {
|
|
68
|
+
client_id: this.config.clientId,
|
|
69
|
+
state: stateId,
|
|
70
|
+
...extraParams,
|
|
71
|
+
};
|
|
72
|
+
await this._saveState(stateId, {
|
|
73
|
+
restoreLocation: window.location.href,
|
|
74
|
+
scopes: [...this.config.scopes],
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
url: encodeURL(this.config.logout, logoutParams),
|
|
78
|
+
stateId,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
54
81
|
/**
|
|
55
82
|
* @param {string} id
|
|
56
83
|
* @param {StoredState} storedState
|
|
@@ -15,7 +15,7 @@ class Tabs extends PureComponent {
|
|
|
15
15
|
const { selected, children } = this.props;
|
|
16
16
|
const childrenArray = React.Children.toArray(children).filter(Boolean);
|
|
17
17
|
const selectedIndex = childrenArray.findIndex((tab, i) => getTabId(tab, i) === selected);
|
|
18
|
-
const actualSelectedIndex = selectedIndex === -1 ?
|
|
18
|
+
const actualSelectedIndex = selectedIndex === -1 ? childrenArray.findIndex(tab => tab.type !== CustomItem) : selectedIndex;
|
|
19
19
|
const selectedItem = childrenArray[actualSelectedIndex];
|
|
20
20
|
return { selectedItem, selectedKey: getTabId(selectedItem, actualSelectedIndex) };
|
|
21
21
|
}
|