forked from deriv-com/smarttrader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.js
192 lines (164 loc) · 7.52 KB
/
auth.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
const {
AppIDConstants,
LocalStorageConstants,
LocalStorageUtils,
URLConstants,
WebSocketUtils,
} = require('@deriv-com/utils');
const Cookies = require('js-cookie');
const requestOidcAuthentication = require('@deriv-com/auth-client').requestOidcAuthentication;
const OAuth2Logout = require('@deriv-com/auth-client').OAuth2Logout;
const Analytics = require('./analytics');
const Language = require('./language');
export const DEFAULT_OAUTH_LOGOUT_URL = 'https://oauth.deriv.com/oauth2/sessions/logout';
export const DEFAULT_OAUTH_ORIGIN_URL = 'https://oauth.deriv.com';
const SocketURL = {
[URLConstants.derivP2pProduction]: 'blue.derivws.com',
[URLConstants.derivP2pStaging] : 'red.derivws.com',
};
export const getServerInfo = () => {
const origin = window.location.origin;
const hostname = window.location.hostname;
const existingAppId = LocalStorageUtils.getValue(LocalStorageConstants.configAppId);
const existingServerUrl = LocalStorageUtils.getValue(LocalStorageConstants.configServerURL);
// since we don't have official app_id for staging,
// we will use the red server with app_id=62019 for the staging-p2p.deriv.com for now
// to fix the login issue
if (origin === URLConstants.derivP2pStaging && (!existingAppId || !existingServerUrl)) {
LocalStorageUtils.setValue(LocalStorageConstants.configServerURL, SocketURL[origin]);
LocalStorageUtils.setValue(LocalStorageConstants.configAppId, `${AppIDConstants.domainAppId[hostname]}`);
}
const serverUrl = LocalStorageUtils.getValue(LocalStorageConstants.configServerURL) || localStorage.getItem('config.server_url') || 'oauth.deriv.com';
const defaultAppId = WebSocketUtils.getAppId();
const appId = LocalStorageUtils.getValue(LocalStorageConstants.configAppId) || defaultAppId;
const lang = LocalStorageUtils.getValue(LocalStorageConstants.i18nLanguage) || 'en';
return {
appId,
lang,
serverUrl,
};
};
export const getOAuthLogoutUrl = () => {
const { appId, serverUrl } = getServerInfo();
const oauthUrl = appId && serverUrl ? `https://${serverUrl}/oauth2/sessions/logout` : DEFAULT_OAUTH_LOGOUT_URL;
return oauthUrl;
};
export const getOAuthOrigin = () => {
const { appId, serverUrl } = getServerInfo();
const oauthUrl = appId && serverUrl ? `https://${serverUrl}` : DEFAULT_OAUTH_ORIGIN_URL;
return oauthUrl;
};
export const isOAuth2Enabled = () => {
const [OAuth2EnabledApps, OAuth2EnabledAppsInitialised] = Analytics.getGrowthbookFeatureValue({
featureFlag: 'hydra_be',
});
const appId = WebSocketUtils.getAppId();
if (OAuth2EnabledAppsInitialised) {
const FEHydraAppIds = OAuth2EnabledApps?.length
? OAuth2EnabledApps[OAuth2EnabledApps.length - 1]?.enabled_for ?? []
: [];
return FEHydraAppIds.includes(+appId);
}
return false;
};
export const requestOauth2Logout = onWSLogoutAndRedirect => {
const currentLanguage = Language.get();
OAuth2Logout({
WSLogoutAndRedirect : onWSLogoutAndRedirect,
redirectCallbackUri : `${window.location.origin}/${currentLanguage}/callback`,
postLogoutRedirectUri: `${window.location.origin}/${currentLanguage}/trading`,
});
};
export const requestSingleLogout = async (onWSLogoutAndRedirect) => {
const requestSingleLogoutImpl = async () => {
const isLoggedOutCookie = Cookies.get('logged_state') === 'false';
const clientAccounts = JSON.parse(localStorage.getItem('client.accounts') || '{}');
const isClientAccountsPopulated = Object.keys(clientAccounts).length > 0;
const isAuthEnabled = isOAuth2Enabled();
const isCallbackPage = window.location.pathname.includes('callback');
const isEndpointPage = window.location.pathname.includes('endpoint');
if (isLoggedOutCookie && isClientAccountsPopulated && isAuthEnabled && !isCallbackPage && !isEndpointPage) {
await requestOauth2Logout(onWSLogoutAndRedirect);
}
};
const isGrowthbookLoaded = Analytics.isGrowthbookLoaded();
if (!isGrowthbookLoaded) {
let retryInterval = 0;
// this interval is to check if Growthbook is already initialised.
// If not, keep checking it (max 10 times) and SSO if conditions are met
const interval = setInterval(() => {
if (retryInterval > 10) {
clearInterval(interval);
} else {
const isLoaded = Analytics.isGrowthbookLoaded();
if (isLoaded) {
requestSingleLogoutImpl();
clearInterval(interval);
} else {
retryInterval += 1;
}
}
}, 500);
} else {
requestSingleLogoutImpl();
}
};
export const requestSingleSignOn = async () => {
const _requestSingleSignOn = async () => {
// if we have previously logged in,
// this cookie will be set by the Callback page (which is exported from @deriv-com/auth-client library) to true when we have successfully logged in from other apps
const isLoggedInCookie = Cookies.get('logged_state') === 'true';
const clientAccounts = JSON.parse(localStorage.getItem('client.accounts') || '{}');
const isClientAccountsPopulated = Object.keys(clientAccounts).length > 0;
const isAuthEnabled = isOAuth2Enabled();
const isCallbackPage = window.location.pathname.includes('callback');
const isEndpointPage = window.location.pathname.includes('endpoint');
// we only do SSO if:
// we have previously logged-in before from SmartTrader or any other apps (Deriv.app, etc) - isLoggedInCookie
// if we are not in the callback route to prevent re-calling this function - !isCallbackPage
// if client.accounts in localStorage is empty - !isClientAccountsPopulated
// and if feature flag for OIDC Phase 2 is enabled - isAuthEnabled
// Check if any account or its linked account is missing a token
const hasMissingToken = Object.values(clientAccounts).some((account) => {
// Check if current account is missing token
if (!account?.token) {
return true; // No linked accounts and no token
}
return false;
});
const shouldRequestSignOn =
isLoggedInCookie &&
!isCallbackPage &&
!isEndpointPage &&
(!isClientAccountsPopulated ||
(isClientAccountsPopulated && hasMissingToken)) &&
isAuthEnabled;
if (shouldRequestSignOn) {
const currentLanguage = Language.get();
await requestOidcAuthentication({
redirectCallbackUri: `${window.location.origin}/${currentLanguage}/callback`,
});
}
};
const isGrowthbookLoaded = Analytics.isGrowthbookLoaded();
if (!isGrowthbookLoaded) {
let retryInterval = 0;
// this interval is to check if Growthbook is already initialised.
// If not, keep checking it (max 10 times) and SSO if conditions are met
const interval = setInterval(() => {
if (retryInterval > 10) {
clearInterval(interval);
} else {
const isLoaded = Analytics.isGrowthbookLoaded();
if (isLoaded) {
_requestSingleSignOn();
clearInterval(interval);
} else {
retryInterval += 1;
}
}
}, 500);
} else {
_requestSingleSignOn();
}
};