forked from pryv/lib-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLoginButton.js
More file actions
207 lines (184 loc) · 6.21 KB
/
LoginButton.js
File metadata and controls
207 lines (184 loc) · 6.21 KB
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/**
* @license
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
*/
const Cookies = require('./CookieUtils');
const AuthStates = require('../Auth/AuthStates');
const AuthController = require('../Auth/AuthController');
const Messages = require('../Auth/LoginMessages');
const utils = require('../utils');
/* global location, confirm */
/**
* @memberof pryv.Browser
*/
class LoginButton {
constructor (authSettings, service) {
this.authSettings = authSettings;
this.service = service;
this.serviceInfo = service.infoSync();
}
/**
* setup button and load assets
*/
async init () {
// initialize button visuals
setupButton(this);
this.languageCode = this.authSettings.authRequest.languageCode || 'en';
this.messages = Messages(this.languageCode);
// @ts-ignore - loginButtonText is set by setupButton
if (this.loginButtonText) {
await loadAssets(this);
}
// set cookie key for authorization data
this._cookieKey = 'pryv-libjs-' + this.authSettings.authRequest.requestingAppId;
// initialize controller
this.auth = new AuthController(this.authSettings, this.service, this);
await this.auth.init();
return this.service;
}
onClick () {
this.auth.handleClick();
}
async onStateChange (state) {
switch (state.status) {
case AuthStates.LOADING:
this.text = getLoadingMessage(this);
break;
case AuthStates.INITIALIZED:
this.text = getInitializedMessage(this, this.serviceInfo.name);
break;
case AuthStates.NEED_SIGNIN: {
const loginUrl = state.authUrl || state.url; // url is deprecated
if (this.authSettings.authRequest.returnURL) { // open on same page (no Popup)
location.href = loginUrl;
return;
} else {
startLoginScreen(this, loginUrl);
}
break;
}
case AuthStates.AUTHORIZED:
this.text = state.username;
this.saveAuthorizationData({
apiEndpoint: state.apiEndpoint,
username: state.username
});
break;
case AuthStates.SIGNOUT: {
const message = this.messages.SIGNOUT_CONFIRM ? this.messages.SIGNOUT_CONFIRM : 'Logout ?';
if (confirm(message)) {
this.deleteAuthorizationData();
this.auth.init();
}
break;
}
case AuthStates.ERROR:
this.text = getErrorMessage(this, state.message);
break;
default:
console.log('WARNING Unhandled state for Login: ' + state.status);
}
// @ts-ignore - loginButtonText is set by setupButton
if (this.loginButtonText) {
// @ts-ignore
this.loginButtonText.innerHTML = this.text;
}
}
getAuthorizationData () {
return Cookies.get(this._cookieKey);
}
saveAuthorizationData (authData) {
Cookies.set(this._cookieKey, authData);
}
async deleteAuthorizationData () {
Cookies.del(this._cookieKey);
}
/**
* not mandatory to implement as non-browsers don't have this behaviour
* @param {*} authController
*/
async finishAuthProcessAfterRedirection (authController) {
// this step should be applied only for the browser
if (!utils.isBrowser()) return;
// 3. Check if there is a prYvkey as result of "out of page login"
const url = window.location.href;
const pollUrl = retrievePollUrl(url);
if (pollUrl !== null) {
try {
const { body } = await utils.fetchGet(pollUrl);
authController.state = body;
} catch (e) {
authController.state = {
status: AuthStates.ERROR,
message: 'Cannot fetch result',
error: e
};
}
}
function retrievePollUrl (url) {
const params = utils.getQueryParamsFromURL(url);
let pollUrl = null;
if (params.prYvkey) { // deprecated method - To be removed
pollUrl = authController.serviceInfo.access + params.prYvkey;
}
if (params.prYvpoll) {
pollUrl = params.prYvpoll;
}
return pollUrl;
}
}
}
module.exports = LoginButton;
async function startLoginScreen (loginButton, authUrl) {
const screenX = typeof window.screenX !== 'undefined' ? window.screenX : window.screenLeft;
const screenY = typeof window.screenY !== 'undefined' ? window.screenY : window.screenTop;
const outerWidth = typeof window.outerWidth !== 'undefined' ? window.outerWidth : document.body.clientWidth;
const outerHeight = typeof window.outerHeight !== 'undefined' ? window.outerHeight : (document.body.clientHeight - 22);
const width = 400;
const height = 620;
const left = Math.floor(screenX + ((outerWidth - width) / 2));
const top = Math.floor(screenY + ((outerHeight - height) / 2.5));
const features = (
'width=' + width +
',height=' + height +
',left=' + left +
',top=' + top +
',scrollbars=yes'
);
loginButton.popup = window.open(authUrl, 'prYv Sign-in', features);
if (!loginButton.popup) {
// loginButton.auth.stopAuthRequest('FAILED_TO_OPEN_WINDOW');
console.log('Pop-up blocked. A second click should allow it.');
} else if (window.focus) {
loginButton.popup.focus();
}
}
function setupButton (loginBtn) {
loginBtn.loginButtonSpan = document.getElementById(loginBtn.authSettings.spanButtonID);
if (!loginBtn.loginButtonSpan) {
console.log('WARNING: pryv.Browser initialized with no spanButtonID');
} else {
// up to the time the button is loaded use the Span to display eventual
// error messages
loginBtn.loginButtonText = loginBtn.loginButtonSpan;
// bind actions dynamically to the button click
loginBtn.loginButtonSpan.addEventListener('click', loginBtn.onClick.bind(loginBtn));
}
}
/**
* Loads the style from the service info
*/
async function loadAssets (loginBtn) {
const assets = await loginBtn.service.assets();
loginBtn.loginButtonSpan.innerHTML = await assets.loginButtonGetHTML();
loginBtn.loginButtonText = document.getElementById('pryv-access-btn-text');
}
function getErrorMessage (loginButton, message) {
return loginButton.messages.ERROR + ': ' + message;
}
function getLoadingMessage (loginButton) {
return loginButton.messages.LOADING;
}
function getInitializedMessage (loginButton, serviceName) {
return loginButton.messages.LOGIN + ': ' + serviceName;
}