pict-section-login 0.0.1
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/example_applications/custom_login/Custom-Login-Application.js +75 -0
- package/example_applications/custom_login/html/index.html +110 -0
- package/example_applications/custom_login/package.json +27 -0
- package/example_applications/harness_app/Harness-App-Application.js +167 -0
- package/example_applications/harness_app/Harness-App-Configuration.json +4 -0
- package/example_applications/harness_app/html/index.html +90 -0
- package/example_applications/harness_app/package.json +28 -0
- package/example_applications/harness_app/providers/PictRouter-HarnessApp.json +24 -0
- package/example_applications/harness_app/views/PictView-HarnessApp-Books.js +172 -0
- package/example_applications/harness_app/views/PictView-HarnessApp-Dashboard.js +158 -0
- package/example_applications/harness_app/views/PictView-HarnessApp-Layout.js +86 -0
- package/example_applications/harness_app/views/PictView-HarnessApp-Login.js +58 -0
- package/example_applications/harness_app/views/PictView-HarnessApp-TopBar.js +157 -0
- package/example_applications/harness_app/views/PictView-HarnessApp-Users.js +188 -0
- package/example_applications/oauth_login/OAuth-Login-Application.js +78 -0
- package/example_applications/oauth_login/html/index.html +57 -0
- package/example_applications/oauth_login/package.json +27 -0
- package/example_applications/orator_login/Orator-Login-Application.js +61 -0
- package/example_applications/orator_login/html/index.html +51 -0
- package/example_applications/orator_login/package.json +27 -0
- package/package.json +53 -0
- package/source/Pict-Section-Login-DefaultConfiguration.js +265 -0
- package/source/Pict-Section-Login.js +533 -0
- package/test/Browser_Integration_tests.js +588 -0
- package/test/Pict-Section-Login_tests.js +593 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
const libPictViewClass = require('pict-view');
|
|
2
|
+
const _DefaultConfiguration = require('./Pict-Section-Login-DefaultConfiguration.js');
|
|
3
|
+
|
|
4
|
+
class PictSectionLogin extends libPictViewClass
|
|
5
|
+
{
|
|
6
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
7
|
+
{
|
|
8
|
+
let tmpOptions = Object.assign({}, _DefaultConfiguration, pOptions);
|
|
9
|
+
super(pFable, tmpOptions, pServiceHash);
|
|
10
|
+
|
|
11
|
+
// --- State ---
|
|
12
|
+
this.authenticated = false;
|
|
13
|
+
this.sessionData = null;
|
|
14
|
+
this.oauthProviders = [];
|
|
15
|
+
|
|
16
|
+
this.initialRenderComplete = false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ===== Lifecycle Hooks =====
|
|
20
|
+
|
|
21
|
+
onBeforeInitialize()
|
|
22
|
+
{
|
|
23
|
+
return super.onBeforeInitialize();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onAfterRender(pRenderable)
|
|
27
|
+
{
|
|
28
|
+
// Inject all registered CSS into the DOM
|
|
29
|
+
this.pict.CSSMap.injectCSS();
|
|
30
|
+
|
|
31
|
+
if (!this.initialRenderComplete)
|
|
32
|
+
{
|
|
33
|
+
this.onAfterInitialRender();
|
|
34
|
+
this.initialRenderComplete = true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return super.onAfterRender(pRenderable);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onAfterInitialRender()
|
|
41
|
+
{
|
|
42
|
+
// Populate the form (or status) into the wrapper placeholders
|
|
43
|
+
this._updateView();
|
|
44
|
+
|
|
45
|
+
if (this.options.CheckSessionOnLoad)
|
|
46
|
+
{
|
|
47
|
+
this.checkSession();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (this.options.ShowOAuthProviders)
|
|
51
|
+
{
|
|
52
|
+
this.loadOAuthProviders();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ===== Public API =====
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Authenticate with username and password.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} pUsername - The username / login ID
|
|
62
|
+
* @param {string} pPassword - The password
|
|
63
|
+
* @param {function} [fCallback] - Optional callback(pError, pSessionData)
|
|
64
|
+
*/
|
|
65
|
+
login(pUsername, pPassword, fCallback)
|
|
66
|
+
{
|
|
67
|
+
if (typeof (fCallback) !== 'function')
|
|
68
|
+
{
|
|
69
|
+
fCallback = () => {};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this._clearError();
|
|
73
|
+
|
|
74
|
+
let tmpFetchOptions = {};
|
|
75
|
+
let tmpURL = this.options.LoginEndpoint;
|
|
76
|
+
|
|
77
|
+
if (this.options.LoginMethod === 'GET')
|
|
78
|
+
{
|
|
79
|
+
tmpURL = tmpURL + '/' + encodeURIComponent(pUsername) + '/' + encodeURIComponent(pPassword);
|
|
80
|
+
tmpFetchOptions.method = 'GET';
|
|
81
|
+
}
|
|
82
|
+
else
|
|
83
|
+
{
|
|
84
|
+
tmpFetchOptions.method = 'POST';
|
|
85
|
+
tmpFetchOptions.headers = { 'Content-Type': 'application/json' };
|
|
86
|
+
tmpFetchOptions.body = JSON.stringify({ UserName: pUsername, Password: pPassword });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
fetch(tmpURL, tmpFetchOptions)
|
|
90
|
+
.then((pResponse) =>
|
|
91
|
+
{
|
|
92
|
+
return pResponse.json();
|
|
93
|
+
})
|
|
94
|
+
.then((pData) =>
|
|
95
|
+
{
|
|
96
|
+
if (pData && pData.LoggedIn)
|
|
97
|
+
{
|
|
98
|
+
this.authenticated = true;
|
|
99
|
+
this.sessionData = pData;
|
|
100
|
+
this._storeSessionData(pData);
|
|
101
|
+
this._updateView();
|
|
102
|
+
this.onLoginSuccess(pData);
|
|
103
|
+
this._solveApp();
|
|
104
|
+
return fCallback(null, pData);
|
|
105
|
+
}
|
|
106
|
+
else
|
|
107
|
+
{
|
|
108
|
+
let tmpError = (pData && pData.Error) ? pData.Error : 'Authentication failed.';
|
|
109
|
+
this._displayError(tmpError);
|
|
110
|
+
this.onLoginFailed(tmpError);
|
|
111
|
+
return fCallback(tmpError);
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
.catch((pError) =>
|
|
115
|
+
{
|
|
116
|
+
let tmpMessage = 'Login request failed.';
|
|
117
|
+
this.log.error('PictSectionLogin login error: ' + pError.message);
|
|
118
|
+
this._displayError(tmpMessage);
|
|
119
|
+
this.onLoginFailed(tmpMessage);
|
|
120
|
+
return fCallback(tmpMessage);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* End the current session.
|
|
126
|
+
*
|
|
127
|
+
* @param {function} [fCallback] - Optional callback(pError)
|
|
128
|
+
*/
|
|
129
|
+
logout(fCallback)
|
|
130
|
+
{
|
|
131
|
+
if (typeof (fCallback) !== 'function')
|
|
132
|
+
{
|
|
133
|
+
fCallback = () => {};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fetch(this.options.LogoutEndpoint)
|
|
137
|
+
.then((pResponse) =>
|
|
138
|
+
{
|
|
139
|
+
return pResponse.json();
|
|
140
|
+
})
|
|
141
|
+
.then(() =>
|
|
142
|
+
{
|
|
143
|
+
this.authenticated = false;
|
|
144
|
+
this.sessionData = null;
|
|
145
|
+
this._storeSessionData(null);
|
|
146
|
+
this._updateView();
|
|
147
|
+
this.onLogout();
|
|
148
|
+
this._solveApp();
|
|
149
|
+
return fCallback(null);
|
|
150
|
+
})
|
|
151
|
+
.catch((pError) =>
|
|
152
|
+
{
|
|
153
|
+
this.log.error('PictSectionLogin logout error: ' + pError.message);
|
|
154
|
+
// Clear local state even if network failed
|
|
155
|
+
this.authenticated = false;
|
|
156
|
+
this.sessionData = null;
|
|
157
|
+
this._storeSessionData(null);
|
|
158
|
+
this._updateView();
|
|
159
|
+
this.onLogout();
|
|
160
|
+
this._solveApp();
|
|
161
|
+
return fCallback(pError.message);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Check whether an existing session is active (e.g. from a cookie).
|
|
167
|
+
*
|
|
168
|
+
* @param {function} [fCallback] - Optional callback(pError, pSessionData)
|
|
169
|
+
*/
|
|
170
|
+
checkSession(fCallback)
|
|
171
|
+
{
|
|
172
|
+
if (typeof (fCallback) !== 'function')
|
|
173
|
+
{
|
|
174
|
+
fCallback = () => {};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
fetch(this.options.CheckSessionEndpoint)
|
|
178
|
+
.then((pResponse) =>
|
|
179
|
+
{
|
|
180
|
+
return pResponse.json();
|
|
181
|
+
})
|
|
182
|
+
.then((pData) =>
|
|
183
|
+
{
|
|
184
|
+
if (pData && pData.LoggedIn)
|
|
185
|
+
{
|
|
186
|
+
this.authenticated = true;
|
|
187
|
+
this.sessionData = pData;
|
|
188
|
+
this._storeSessionData(pData);
|
|
189
|
+
this._updateView();
|
|
190
|
+
}
|
|
191
|
+
this.onSessionChecked(pData);
|
|
192
|
+
this._solveApp();
|
|
193
|
+
return fCallback(null, pData);
|
|
194
|
+
})
|
|
195
|
+
.catch((pError) =>
|
|
196
|
+
{
|
|
197
|
+
this.log.error('PictSectionLogin checkSession error: ' + pError.message);
|
|
198
|
+
this.onSessionChecked(null);
|
|
199
|
+
return fCallback(pError.message);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Fetch available OAuth providers and render buttons.
|
|
205
|
+
*
|
|
206
|
+
* @param {function} [fCallback] - Optional callback(pError, pProviders)
|
|
207
|
+
*/
|
|
208
|
+
loadOAuthProviders(fCallback)
|
|
209
|
+
{
|
|
210
|
+
if (typeof (fCallback) !== 'function')
|
|
211
|
+
{
|
|
212
|
+
fCallback = () => {};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
fetch(this.options.OAuthProvidersEndpoint)
|
|
216
|
+
.then((pResponse) =>
|
|
217
|
+
{
|
|
218
|
+
return pResponse.json();
|
|
219
|
+
})
|
|
220
|
+
.then((pData) =>
|
|
221
|
+
{
|
|
222
|
+
if (pData && Array.isArray(pData.Providers))
|
|
223
|
+
{
|
|
224
|
+
this.oauthProviders = pData.Providers;
|
|
225
|
+
this._renderOAuthButtons();
|
|
226
|
+
}
|
|
227
|
+
return fCallback(null, this.oauthProviders);
|
|
228
|
+
})
|
|
229
|
+
.catch((pError) =>
|
|
230
|
+
{
|
|
231
|
+
this.log.warn('PictSectionLogin loadOAuthProviders: ' + pError.message);
|
|
232
|
+
return fCallback(pError.message);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ===== Overridable Hooks =====
|
|
237
|
+
// Developers override these for custom post-login/logout behavior.
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Called after a successful login.
|
|
241
|
+
* @param {object} pSessionData - The session data from the server
|
|
242
|
+
*/
|
|
243
|
+
onLoginSuccess(pSessionData)
|
|
244
|
+
{
|
|
245
|
+
// Override in subclass or instance
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Called after a failed login attempt.
|
|
250
|
+
* @param {string} pError - The error message
|
|
251
|
+
*/
|
|
252
|
+
onLoginFailed(pError)
|
|
253
|
+
{
|
|
254
|
+
// Override in subclass or instance
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Called after a successful logout.
|
|
259
|
+
*/
|
|
260
|
+
onLogout()
|
|
261
|
+
{
|
|
262
|
+
// Override in subclass or instance
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Called after a session check completes.
|
|
267
|
+
* @param {object|null} pSessionData - The session data, or null on error
|
|
268
|
+
*/
|
|
269
|
+
onSessionChecked(pSessionData)
|
|
270
|
+
{
|
|
271
|
+
// Override in subclass or instance
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ===== Internal Helpers =====
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Wire up DOM event handlers on the login form and logout button.
|
|
278
|
+
*/
|
|
279
|
+
_wireFormEvents()
|
|
280
|
+
{
|
|
281
|
+
let tmpFormElements = this.services.ContentAssignment.getElement('#pict-login-form');
|
|
282
|
+
if (tmpFormElements && tmpFormElements.length > 0)
|
|
283
|
+
{
|
|
284
|
+
let tmpForm = tmpFormElements[0];
|
|
285
|
+
tmpForm.addEventListener('submit', (pEvent) =>
|
|
286
|
+
{
|
|
287
|
+
pEvent.preventDefault();
|
|
288
|
+
let tmpUsernameInput = tmpForm.querySelector('#pict-login-username');
|
|
289
|
+
let tmpPasswordInput = tmpForm.querySelector('#pict-login-password');
|
|
290
|
+
|
|
291
|
+
let tmpUsername = tmpUsernameInput ? tmpUsernameInput.value : '';
|
|
292
|
+
let tmpPassword = tmpPasswordInput ? tmpPasswordInput.value : '';
|
|
293
|
+
|
|
294
|
+
if (!tmpUsername)
|
|
295
|
+
{
|
|
296
|
+
this._displayError('Please enter a username.');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
this.login(tmpUsername, tmpPassword);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
let tmpLogoutElements = this.services.ContentAssignment.getElement('#pict-login-logout');
|
|
305
|
+
if (tmpLogoutElements && tmpLogoutElements.length > 0)
|
|
306
|
+
{
|
|
307
|
+
tmpLogoutElements[0].addEventListener('click', () =>
|
|
308
|
+
{
|
|
309
|
+
this.logout();
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Show an error message in the error area.
|
|
316
|
+
* @param {string} pMessage - The error text
|
|
317
|
+
*/
|
|
318
|
+
_displayError(pMessage)
|
|
319
|
+
{
|
|
320
|
+
let tmpErrorElements = this.services.ContentAssignment.getElement('#pict-login-error');
|
|
321
|
+
if (tmpErrorElements && tmpErrorElements.length > 0)
|
|
322
|
+
{
|
|
323
|
+
let tmpErrorEl = tmpErrorElements[0];
|
|
324
|
+
tmpErrorEl.textContent = pMessage;
|
|
325
|
+
tmpErrorEl.style.display = 'block';
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Hide the error area.
|
|
331
|
+
*/
|
|
332
|
+
_clearError()
|
|
333
|
+
{
|
|
334
|
+
let tmpErrorElements = this.services.ContentAssignment.getElement('#pict-login-error');
|
|
335
|
+
if (tmpErrorElements && tmpErrorElements.length > 0)
|
|
336
|
+
{
|
|
337
|
+
let tmpErrorEl = tmpErrorElements[0];
|
|
338
|
+
tmpErrorEl.textContent = '';
|
|
339
|
+
tmpErrorEl.style.display = 'none';
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Re-render the view to reflect current authentication state.
|
|
345
|
+
* Shows the login form when unauthenticated, or the status bar when authenticated.
|
|
346
|
+
*/
|
|
347
|
+
_updateView()
|
|
348
|
+
{
|
|
349
|
+
let tmpFormAreaElements = this.services.ContentAssignment.getElement('#pict-login-form-area');
|
|
350
|
+
let tmpStatusAreaElements = this.services.ContentAssignment.getElement('#pict-login-status-area');
|
|
351
|
+
let tmpOAuthAreaElements = this.services.ContentAssignment.getElement('#pict-login-oauth-area');
|
|
352
|
+
|
|
353
|
+
if (this.authenticated && this.sessionData)
|
|
354
|
+
{
|
|
355
|
+
// --- Authenticated: show status, hide form ---
|
|
356
|
+
if (tmpFormAreaElements && tmpFormAreaElements.length > 0)
|
|
357
|
+
{
|
|
358
|
+
tmpFormAreaElements[0].style.display = 'none';
|
|
359
|
+
}
|
|
360
|
+
if (tmpOAuthAreaElements && tmpOAuthAreaElements.length > 0)
|
|
361
|
+
{
|
|
362
|
+
tmpOAuthAreaElements[0].style.display = 'none';
|
|
363
|
+
}
|
|
364
|
+
if (tmpStatusAreaElements && tmpStatusAreaElements.length > 0)
|
|
365
|
+
{
|
|
366
|
+
let tmpStatusArea = tmpStatusAreaElements[0];
|
|
367
|
+
tmpStatusArea.style.display = 'block';
|
|
368
|
+
|
|
369
|
+
// Render the status template
|
|
370
|
+
let tmpStatusHTML = this.pict.parseTemplateByHash('Pict-Login-Template-Status', {});
|
|
371
|
+
tmpStatusArea.innerHTML = tmpStatusHTML;
|
|
372
|
+
|
|
373
|
+
// Populate display values
|
|
374
|
+
let tmpDisplayName = '';
|
|
375
|
+
let tmpDisplayID = '';
|
|
376
|
+
|
|
377
|
+
if (this.sessionData.UserRecord)
|
|
378
|
+
{
|
|
379
|
+
tmpDisplayName = this.sessionData.UserRecord.FullName
|
|
380
|
+
|| this.sessionData.UserRecord.LoginID
|
|
381
|
+
|| this.sessionData.UserRecord.Email
|
|
382
|
+
|| '';
|
|
383
|
+
tmpDisplayID = this.sessionData.UserRecord.IDUser || this.sessionData.UserID || '';
|
|
384
|
+
}
|
|
385
|
+
else if (this.sessionData.UserID)
|
|
386
|
+
{
|
|
387
|
+
tmpDisplayID = this.sessionData.UserID;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
let tmpNameElements = tmpStatusArea.querySelectorAll('#pict-login-display-name');
|
|
391
|
+
if (tmpNameElements.length > 0)
|
|
392
|
+
{
|
|
393
|
+
tmpNameElements[0].textContent = tmpDisplayName;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
let tmpIDElements = tmpStatusArea.querySelectorAll('#pict-login-display-id');
|
|
397
|
+
if (tmpIDElements.length > 0)
|
|
398
|
+
{
|
|
399
|
+
if (tmpDisplayID)
|
|
400
|
+
{
|
|
401
|
+
tmpIDElements[0].textContent = 'ID ' + tmpDisplayID;
|
|
402
|
+
}
|
|
403
|
+
else
|
|
404
|
+
{
|
|
405
|
+
tmpIDElements[0].style.display = 'none';
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Wire logout button
|
|
410
|
+
let tmpLogoutBtn = tmpStatusArea.querySelector('#pict-login-logout');
|
|
411
|
+
if (tmpLogoutBtn)
|
|
412
|
+
{
|
|
413
|
+
tmpLogoutBtn.addEventListener('click', () =>
|
|
414
|
+
{
|
|
415
|
+
this.logout();
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
this._clearError();
|
|
420
|
+
}
|
|
421
|
+
else
|
|
422
|
+
{
|
|
423
|
+
// --- Unauthenticated: show form, hide status ---
|
|
424
|
+
if (tmpStatusAreaElements && tmpStatusAreaElements.length > 0)
|
|
425
|
+
{
|
|
426
|
+
tmpStatusAreaElements[0].style.display = 'none';
|
|
427
|
+
tmpStatusAreaElements[0].innerHTML = '';
|
|
428
|
+
}
|
|
429
|
+
if (tmpFormAreaElements && tmpFormAreaElements.length > 0)
|
|
430
|
+
{
|
|
431
|
+
let tmpFormArea = tmpFormAreaElements[0];
|
|
432
|
+
tmpFormArea.style.display = 'block';
|
|
433
|
+
|
|
434
|
+
// Re-render form if empty
|
|
435
|
+
if (!tmpFormArea.querySelector('#pict-login-form'))
|
|
436
|
+
{
|
|
437
|
+
let tmpFormHTML = this.pict.parseTemplateByHash('Pict-Login-Template-Form', {});
|
|
438
|
+
tmpFormArea.innerHTML = tmpFormHTML;
|
|
439
|
+
this._wireFormEvents();
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (tmpOAuthAreaElements && tmpOAuthAreaElements.length > 0)
|
|
443
|
+
{
|
|
444
|
+
if (this.options.ShowOAuthProviders && this.oauthProviders.length > 0)
|
|
445
|
+
{
|
|
446
|
+
tmpOAuthAreaElements[0].style.display = 'block';
|
|
447
|
+
}
|
|
448
|
+
else
|
|
449
|
+
{
|
|
450
|
+
tmpOAuthAreaElements[0].style.display = 'none';
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Render OAuth provider buttons into the OAuth area.
|
|
458
|
+
*/
|
|
459
|
+
_renderOAuthButtons()
|
|
460
|
+
{
|
|
461
|
+
let tmpOAuthAreaElements = this.services.ContentAssignment.getElement('#pict-login-oauth-area');
|
|
462
|
+
if (!tmpOAuthAreaElements || tmpOAuthAreaElements.length < 1)
|
|
463
|
+
{
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (!this.oauthProviders || this.oauthProviders.length < 1)
|
|
468
|
+
{
|
|
469
|
+
tmpOAuthAreaElements[0].style.display = 'none';
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Render the OAuth container template
|
|
474
|
+
let tmpOAuthHTML = this.pict.parseTemplateByHash('Pict-Login-Template-OAuthProviders', {});
|
|
475
|
+
tmpOAuthAreaElements[0].innerHTML = tmpOAuthHTML;
|
|
476
|
+
tmpOAuthAreaElements[0].style.display = 'block';
|
|
477
|
+
|
|
478
|
+
// Build individual provider buttons
|
|
479
|
+
let tmpButtonContainer = tmpOAuthAreaElements[0].querySelector('#pict-login-oauth-buttons');
|
|
480
|
+
if (!tmpButtonContainer)
|
|
481
|
+
{
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
let tmpButtonsHTML = '';
|
|
486
|
+
for (let i = 0; i < this.oauthProviders.length; i++)
|
|
487
|
+
{
|
|
488
|
+
let tmpProvider = this.oauthProviders[i];
|
|
489
|
+
let tmpName = tmpProvider.Name || 'provider';
|
|
490
|
+
let tmpBeginURL = tmpProvider.BeginURL || (this.options.OAuthBeginEndpoint + '/' + tmpName);
|
|
491
|
+
let tmpDisplayName = tmpName.charAt(0).toUpperCase() + tmpName.slice(1);
|
|
492
|
+
let tmpCSSModifier = tmpName.toLowerCase();
|
|
493
|
+
|
|
494
|
+
tmpButtonsHTML += '<a class="pict-login-oauth-btn pict-login-oauth-btn--' + tmpCSSModifier + '" href="' + tmpBeginURL + '">Sign in with ' + tmpDisplayName + '</a>';
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
tmpButtonContainer.innerHTML = tmpButtonsHTML;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Store session data at the configured Pict address.
|
|
502
|
+
* @param {object|null} pData - Session data to store
|
|
503
|
+
*/
|
|
504
|
+
_storeSessionData(pData)
|
|
505
|
+
{
|
|
506
|
+
if (this.options.SessionDataAddress)
|
|
507
|
+
{
|
|
508
|
+
let tmpAddressSpace =
|
|
509
|
+
{
|
|
510
|
+
Fable: this.fable,
|
|
511
|
+
Pict: this.fable,
|
|
512
|
+
AppData: this.pict.AppData,
|
|
513
|
+
Bundle: this.pict.Bundle
|
|
514
|
+
};
|
|
515
|
+
this.fable.manifest.setValueByHash(tmpAddressSpace, this.options.SessionDataAddress, pData);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Trigger a solve on the PictApplication if one exists.
|
|
521
|
+
*/
|
|
522
|
+
_solveApp()
|
|
523
|
+
{
|
|
524
|
+
if (this.pict && this.pict.PictApplication && typeof (this.pict.PictApplication.solve) === 'function')
|
|
525
|
+
{
|
|
526
|
+
this.pict.PictApplication.solve();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
module.exports = PictSectionLogin;
|
|
532
|
+
|
|
533
|
+
module.exports.default_configuration = _DefaultConfiguration;
|