@idea-ionic/auth 6.12.3 → 7.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.
Files changed (43) hide show
  1. package/environment.d.ts +7 -0
  2. package/esm2022/environment.mjs +34 -0
  3. package/esm2022/src/auth.module.mjs +84 -0
  4. package/esm2022/src/auth.service.mjs +479 -0
  5. package/esm2022/src/confirmPassword.page.mjs +70 -0
  6. package/esm2022/src/forgotPassword.page.mjs +41 -0
  7. package/{esm2020 → esm2022}/src/mfaChallenge.page.mjs +5 -5
  8. package/esm2022/src/newPassword.page.mjs +62 -0
  9. package/esm2022/src/passwordPolicy.component.mjs +64 -0
  10. package/esm2022/src/resendLink.page.mjs +47 -0
  11. package/{esm2020 → esm2022}/src/setupMFA/setupMFA.module.mjs +5 -5
  12. package/{esm2020 → esm2022}/src/setupMFA/setupMFAButton.component.mjs +4 -4
  13. package/{esm2020 → esm2022}/src/setupMFA/setupMFAModal.component.mjs +4 -4
  14. package/esm2022/src/setupMFA.page.mjs +24 -0
  15. package/esm2022/src/signIn.page.mjs +82 -0
  16. package/esm2022/src/signUp.page.mjs +79 -0
  17. package/fesm2022/idea-ionic-auth.mjs +1126 -0
  18. package/fesm2022/idea-ionic-auth.mjs.map +1 -0
  19. package/package.json +17 -23
  20. package/src/auth.module.d.ts +8 -7
  21. package/src/auth.service.d.ts +11 -0
  22. package/src/confirmPassword.page.d.ts +12 -3
  23. package/src/newPassword.page.d.ts +12 -3
  24. package/src/passwordPolicy.component.d.ts +13 -0
  25. package/src/setupMFA/setupMFAButton.component.d.ts +1 -1
  26. package/src/signIn.page.d.ts +2 -2
  27. package/src/signUp.page.d.ts +12 -3
  28. package/esm2020/environment.mjs +0 -26
  29. package/esm2020/src/auth.module.mjs +0 -81
  30. package/esm2020/src/auth.service.mjs +0 -443
  31. package/esm2020/src/confirmPassword.page.mjs +0 -53
  32. package/esm2020/src/forgotPassword.page.mjs +0 -41
  33. package/esm2020/src/newPassword.page.mjs +0 -45
  34. package/esm2020/src/resendLink.page.mjs +0 -47
  35. package/esm2020/src/setupMFA.page.mjs +0 -24
  36. package/esm2020/src/signIn.page.mjs +0 -82
  37. package/esm2020/src/signUp.page.mjs +0 -65
  38. package/fesm2015/idea-ionic-auth.mjs +0 -1019
  39. package/fesm2015/idea-ionic-auth.mjs.map +0 -1
  40. package/fesm2020/idea-ionic-auth.mjs +0 -988
  41. package/fesm2020/idea-ionic-auth.mjs.map +0 -1
  42. /package/{esm2020 → esm2022}/idea-ionic-auth.mjs +0 -0
  43. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
@@ -0,0 +1,1126 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, Component, EventEmitter, Input, Output, NgModule } from '@angular/core';
3
+ import * as i4 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i5 from '@angular/forms';
6
+ import { FormsModule } from '@angular/forms';
7
+ import * as i1 from '@ionic/angular';
8
+ import { IonicModule } from '@ionic/angular';
9
+ import * as i2$1 from '@angular/router';
10
+ import { RouterModule } from '@angular/router';
11
+ import * as i2 from '@idea-ionic/common';
12
+ import { IDEATranslationsModule } from '@idea-ionic/common';
13
+ import { Browser } from '@capacitor/browser';
14
+ import { CognitoUserPool, AuthenticationDetails, CognitoUser, CognitoUserAttribute, CognitoRefreshToken } from 'amazon-cognito-identity-js';
15
+ import { environment } from '@env';
16
+ import { isEmpty } from 'idea-toolbox';
17
+ import { toCanvas } from 'qrcode';
18
+
19
+ /**
20
+ * The name of the Cognito's user attribute which contains the key of the last device to login in this project.
21
+ */
22
+ const DEVICE_KEY_ATTRIBUTE = 'custom:'.concat(environment.idea.project);
23
+ /**
24
+ * Cognito wrapper to manage the authentication flow.
25
+ *
26
+ * Note: in IDEA's Cognito users pools, the email is an alias of the username.
27
+ */
28
+ class IDEAAuthService {
29
+ constructor(storage) {
30
+ this.storage = storage;
31
+ this.mfaProjectName = environment.idea.app.title ?? environment.idea.project;
32
+ this.passwordPolicy = environment.idea.auth.passwordPolicy;
33
+ this.userPool = new CognitoUserPool({
34
+ UserPoolId: environment.aws.cognito.userPoolId,
35
+ ClientId: environment.aws.cognito.userPoolClientId
36
+ });
37
+ }
38
+ /**
39
+ * Prepare the necessary structure to get authorized in Cognito.
40
+ */
41
+ prepareAuthDetails(username, pwd) {
42
+ return new AuthenticationDetails({ Username: username, Password: pwd });
43
+ }
44
+ /**
45
+ * Prepare the necessary structure to identify a Cognito user.
46
+ */
47
+ prepareCognitoUser(username) {
48
+ return new CognitoUser({ Username: username, Pool: this.userPool });
49
+ }
50
+ /**
51
+ * Prepare a user attribute (they are all strings) in Cognito's format.
52
+ */
53
+ prepareUserAttribute(name, value) {
54
+ return new CognitoUserAttribute({ Name: name, Value: value });
55
+ }
56
+ /**
57
+ * Perform a login through username and password.
58
+ */
59
+ login(username, password) {
60
+ return new Promise((resolve, reject) => {
61
+ const user = this.prepareCognitoUser(username);
62
+ user.authenticateUser(this.prepareAuthDetails(username, password), {
63
+ onSuccess: () => resolve(environment.idea.auth.forceLoginWithMFA ? LoginOutcomeActions.MFA_SETUP : LoginOutcomeActions.NONE),
64
+ onFailure: (err) => reject(err),
65
+ newPasswordRequired: () => {
66
+ this.challengeUsername = username;
67
+ this.challengePassword = password;
68
+ resolve(LoginOutcomeActions.NEW_PASSWORD);
69
+ },
70
+ totpRequired: () => {
71
+ this.challengeUsername = username;
72
+ this.challengePassword = password;
73
+ resolve(LoginOutcomeActions.MFA_CHALLENGE);
74
+ }
75
+ });
76
+ });
77
+ }
78
+ /**
79
+ * Complete the new password flow in the authentication.
80
+ */
81
+ confirmNewPassword(newPassword) {
82
+ return new Promise((resolve, reject) => {
83
+ const user = this.prepareCognitoUser(this.challengeUsername);
84
+ user.authenticateUser(this.prepareAuthDetails(this.challengeUsername, this.challengePassword), {
85
+ onSuccess: () => resolve(),
86
+ onFailure: (err) => reject(err),
87
+ newPasswordRequired: () => user.completeNewPasswordChallenge(newPassword, {}, {
88
+ onSuccess: () => {
89
+ this.challengeUsername = null;
90
+ this.challengePassword = null;
91
+ resolve();
92
+ },
93
+ onFailure: (err) => reject(err)
94
+ })
95
+ });
96
+ });
97
+ }
98
+ /**
99
+ * Complete the MFA challenge flow in the authentication.
100
+ */
101
+ completeMFAChallenge(otpCode) {
102
+ return new Promise((resolve, reject) => {
103
+ const user = this.prepareCognitoUser(this.challengeUsername);
104
+ user.authenticateUser(this.prepareAuthDetails(this.challengeUsername, this.challengePassword), {
105
+ onSuccess: () => resolve(),
106
+ onFailure: (err) => reject(err),
107
+ totpRequired: (challengeName) => user.sendMFACode(otpCode, {
108
+ onSuccess: () => {
109
+ this.challengeUsername = null;
110
+ this.challengePassword = null;
111
+ resolve();
112
+ },
113
+ onFailure: err => reject(err)
114
+ }, challengeName)
115
+ });
116
+ });
117
+ }
118
+ /**
119
+ * Register a new user a set its default attributes.
120
+ */
121
+ register(username, password, attributes) {
122
+ attributes = attributes || {};
123
+ return new Promise((resolve, reject) => {
124
+ // add attributes like the email address and the fullname
125
+ const attrs = [];
126
+ for (const prop in attributes)
127
+ if (attributes[prop])
128
+ attrs.push(this.prepareUserAttribute(prop, attributes[prop]));
129
+ // add the email, which is equal to the username for most of our Pools
130
+ if (!attributes.email)
131
+ attrs.push(this.prepareUserAttribute('email', username));
132
+ // register the new user to the pool
133
+ this.userPool.signUp(username, password, attrs, null, (err, res) => {
134
+ if (err)
135
+ return reject(err);
136
+ this.newAccountJustRegistered = username;
137
+ resolve(res.user);
138
+ });
139
+ });
140
+ }
141
+ /**
142
+ * In case new account has just been registered, return the username.
143
+ */
144
+ getNewAccountJustRegistered() {
145
+ return this.newAccountJustRegistered;
146
+ }
147
+ /**
148
+ * Confirm a new registration through the confirmation code sent by Cognito.
149
+ */
150
+ confirmRegistration(username, code) {
151
+ return new Promise((resolve, reject) => {
152
+ this.prepareCognitoUser(username).confirmRegistration(code, true, (err) => err ? reject(err) : resolve());
153
+ });
154
+ }
155
+ /**
156
+ * Send again a confirmation code for a new registration.
157
+ */
158
+ resendConfirmationCode(username) {
159
+ return new Promise((resolve, reject) => {
160
+ this.prepareCognitoUser(username).resendConfirmationCode((err) => (err ? reject(err) : resolve()));
161
+ });
162
+ }
163
+ /**
164
+ * Logout the currently signed-in user.
165
+ */
166
+ logout(options) {
167
+ options = Object.assign({ global: false }, options);
168
+ return new Promise((resolve, reject) => {
169
+ // remove the refresh token previosly saved
170
+ this.storage.remove('AuthRefreshToken').then(() =>
171
+ // remove the optional auth details
172
+ this.storage.remove('AuthUserDetails').then(() => {
173
+ // get the user and the session
174
+ const user = this.userPool.getCurrentUser();
175
+ user.getSession(async (err) => {
176
+ // if the session is active, run the online sign-out; otherwise, only the local data has been deleted
177
+ if (err)
178
+ return resolve();
179
+ // if a reference to the device was saved, forget it
180
+ if (environment.idea.auth.singleSimultaneousSession)
181
+ await this.setCurrentDeviceForProject(null);
182
+ // sign-out from the pool (terminate the current session or all the sessions)
183
+ if (options.global)
184
+ user.globalSignOut({ onSuccess: () => resolve(), onFailure: err => reject(err) });
185
+ else {
186
+ user.signOut();
187
+ resolve();
188
+ }
189
+ });
190
+ }));
191
+ });
192
+ }
193
+ /**
194
+ * Send a password reset request.
195
+ */
196
+ forgotPassword(username) {
197
+ return new Promise((resolve, reject) => {
198
+ this.prepareCognitoUser(username).forgotPassword({
199
+ onSuccess: () => resolve(),
200
+ onFailure: (err) => reject(err)
201
+ });
202
+ });
203
+ }
204
+ /**
205
+ * Confirm a new password after a password reset request.
206
+ */
207
+ confirmPassword(username, code, newPwd) {
208
+ return new Promise((resolve, reject) => {
209
+ this.prepareCognitoUser(username).confirmPassword(code, newPwd, {
210
+ onSuccess: () => resolve(),
211
+ onFailure: (err) => reject(err)
212
+ });
213
+ });
214
+ }
215
+ /**
216
+ * Gets the URL for enabling MFA. This URL can be used to generate a QR Code to read with an authenticator app.
217
+ */
218
+ getURLForEnablingMFA() {
219
+ return new Promise((resolve, reject) => {
220
+ const user = this.userPool.getCurrentUser();
221
+ if (!user)
222
+ return reject();
223
+ user.getSession((err) => {
224
+ if (err)
225
+ return reject(err);
226
+ user.associateSoftwareToken({
227
+ associateSecretCode: (secretCode) => resolve(`otpauth://totp/${encodeURI(this.mfaProjectName)}?secret=${secretCode}`),
228
+ onFailure: (err) => reject(err)
229
+ });
230
+ });
231
+ });
232
+ }
233
+ /**
234
+ * Check whether the user has MFA enabled.
235
+ */
236
+ checkIfUserHasMFAEnabled(bypassCache = false) {
237
+ return new Promise((resolve, reject) => {
238
+ const user = this.userPool.getCurrentUser();
239
+ if (!user)
240
+ return reject();
241
+ user.getSession((err) => {
242
+ if (err)
243
+ return reject(err);
244
+ user.getUserData((err, data) => {
245
+ if (err)
246
+ return reject(err);
247
+ const isMFAEnabled = !!(data.UserMFASettingList && data.UserMFASettingList.includes('SOFTWARE_TOKEN_MFA'));
248
+ resolve(isMFAEnabled);
249
+ }, { bypassCache });
250
+ });
251
+ });
252
+ }
253
+ /**
254
+ * Configure a MFA device for the user.
255
+ */
256
+ setMFADevice(otp, mfaDeviceName, enabled = true, preferred = true) {
257
+ return new Promise((resolve, reject) => {
258
+ const user = this.userPool.getCurrentUser();
259
+ if (!user)
260
+ return reject();
261
+ user.getSession((err) => {
262
+ if (err)
263
+ return reject(err);
264
+ user.verifySoftwareToken(otp, mfaDeviceName, {
265
+ onSuccess: () => user.setUserMfaPreference(null, { Enabled: enabled, PreferredMfa: preferred }, (err) => err ? reject(err) : resolve()),
266
+ onFailure: (err) => reject(err)
267
+ });
268
+ });
269
+ });
270
+ }
271
+ /**
272
+ * Enable a new MFA device for the user by inserting an OTP code generated by it.
273
+ */
274
+ enableMFA(otp, mfaDeviceName = 'default') {
275
+ return this.setMFADevice(otp, mfaDeviceName, true, true);
276
+ }
277
+ /**
278
+ * Disable MFA for a user by inserting an OTP code generated by it.
279
+ */
280
+ disableMFA(otp, mfaDeviceName = 'default') {
281
+ return this.setMFADevice(otp, mfaDeviceName, false, false);
282
+ }
283
+ /**
284
+ * Check if a user is currently authenticated.
285
+ * @param offlineAllowed if set and if offline, skip authentication and retrieve data locally
286
+ * @param getFreshIdTokenOnExp cb function to execute when the idToken is refreshed
287
+ */
288
+ isAuthenticated(offlineAllowed, getFreshIdTokenOnExp) {
289
+ return new Promise((resolve, reject) => {
290
+ if (offlineAllowed && !navigator.onLine) {
291
+ this.storage.get('AuthUserDetails').then(userDetails => resolve({ idToken: null, userDetails }));
292
+ // re-execute the method when back online, so that you can retrieve a token to make requests
293
+ window.addEventListener('online', () => this.isAuthenticated(true, getFreshIdTokenOnExp)
294
+ // set the new token as if it was refreshed
295
+ .then(result => getFreshIdTokenOnExp(result.idToken)));
296
+ }
297
+ else {
298
+ const user = this.userPool.getCurrentUser();
299
+ if (!user)
300
+ return reject();
301
+ user.getSession((err, session) => {
302
+ if (err)
303
+ return reject(err);
304
+ user.getUserData((err, data) => {
305
+ if (err)
306
+ return reject(err);
307
+ const isMFAEnabled = !!(data.UserMFASettingList && data.UserMFASettingList.includes('SOFTWARE_TOKEN_MFA'));
308
+ if (!isMFAEnabled && environment.idea.auth.forceLoginWithMFA)
309
+ return reject(new Error(LoginOutcomeActions.MFA_SETUP));
310
+ user.getUserAttributes((e, attributes) => {
311
+ if (e)
312
+ return reject(e);
313
+ // remap user attributes
314
+ const userDetails = {};
315
+ attributes.forEach((a) => (userDetails[a.getName()] = a.getValue()));
316
+ // add the user's groups to the attributes
317
+ const sessionInfo = session.getAccessToken().decodePayload();
318
+ const groups = sessionInfo['cognito:groups'] || [];
319
+ userDetails['groups'] = groups;
320
+ // run some checks considering the user's groups and devices (based on the project's configuration)
321
+ this.runPostAuthChecks(userDetails, err => {
322
+ // in case some check failed, reject the authorisation flow
323
+ if (err)
324
+ return reject(err);
325
+ // (async) save the refresh token so it can be accessed by other procedures
326
+ this.storage.set('AuthRefreshToken', session.getRefreshToken().getToken());
327
+ // set a timer to manage the autorefresh of the idToken (through the refreshToken)
328
+ setTimeout(() => this.refreshSession(user, session.getRefreshToken().getToken(), getFreshIdTokenOnExp), 15 * 60 * 1000); // every 15 minutes
329
+ // (async) if offlineAllowed, save data locally, to use it next time we'll be offline
330
+ if (offlineAllowed)
331
+ this.storage.set('AuthUserDetails', userDetails);
332
+ // return the idToken (to use with API)
333
+ resolve({ idToken: session.getIdToken().getJwtToken(), userDetails });
334
+ });
335
+ });
336
+ }, { bypassCache: true });
337
+ });
338
+ }
339
+ });
340
+ }
341
+ /**
342
+ * Helper to refresh the session every N minutes.
343
+ */
344
+ refreshSession(user, refreshToken, callback) {
345
+ user.refreshSession(new CognitoRefreshToken({ RefreshToken: refreshToken }), (err, session) => {
346
+ if (err) {
347
+ // try again in 1 minute
348
+ setTimeout(() => this.refreshSession(user, refreshToken, callback), 1 * 60 * 1000);
349
+ }
350
+ else {
351
+ // (async) save the refresh token so it can be accessed by other procedures
352
+ this.storage.set('AuthRefreshToken', session.getRefreshToken().getToken());
353
+ // repeat every 15 minutes
354
+ setTimeout(() => this.refreshSession(user, session.getRefreshToken().getToken(), callback), 15 * 60 * 1000);
355
+ // run the callback action, if set
356
+ if (callback)
357
+ callback(session.getIdToken().getJwtToken());
358
+ }
359
+ });
360
+ }
361
+ /**
362
+ * Run some post-auth checks, based on the users groups and on the app's configuration:
363
+ * - users in the Cognito's "admins" grup skip all the following rules.
364
+ * - users in the Cognito's "robots" group can't sign-into front-ends (they serve only back-end purposes).
365
+ * - if `env.idea.auth.singleSimultaneousSession` is on, make sure there is only one active session per user.
366
+ */
367
+ runPostAuthChecks(userDetails, callback) {
368
+ const groups = userDetails['groups'];
369
+ // skip checks if the user is in the "admins" group
370
+ const isAdmin = groups.some(x => x === 'admins');
371
+ if (isAdmin)
372
+ return callback();
373
+ // users in the "robots" group can't sign-into front-ends (they serve only back-end purposes)
374
+ const isRobot = groups.some(x => x === 'robots');
375
+ if (isRobot)
376
+ return callback(new Error('ROBOT_USER'));
377
+ // in case the project limits each account to only one simultaneous session, run a check
378
+ if (environment.idea.auth.singleSimultaneousSession)
379
+ return this.checkForSimultaneousSessions(userDetails, callback);
380
+ // otherwise, we're done
381
+ callback();
382
+ }
383
+ /**
384
+ * Check whether the user signed-into multiple devices.
385
+ */
386
+ async checkForSimultaneousSessions(userDetails, callback) {
387
+ // get or create a key for the current device (~random)
388
+ let currentDeviceKey = await this.storage.get('AuthDeviceKey');
389
+ if (!currentDeviceKey) {
390
+ const randomKey = Math.random().toString(36).substring(10);
391
+ currentDeviceKey = randomKey.concat(String(Date.now()));
392
+ await this.storage.set('AuthDeviceKey', currentDeviceKey);
393
+ }
394
+ // check whether the last device to sign-into this project (if any) is the current one
395
+ const lastDeviceToSignIntoThisProject = userDetails[DEVICE_KEY_ATTRIBUTE];
396
+ // if it's the first user's device to sign-in, save the reference in Cognito and resolve
397
+ if (!lastDeviceToSignIntoThisProject) {
398
+ this.setCurrentDeviceForProject(currentDeviceKey)
399
+ .then(() => callback())
400
+ .catch(() => callback(new Error('CANT_SET_DEVICE')));
401
+ // if the device didn't change, resolve
402
+ }
403
+ else if (lastDeviceToSignIntoThisProject === currentDeviceKey)
404
+ callback();
405
+ // othwerwise, report there is more than one simultaneous session
406
+ else
407
+ callback(new Error('SIMULTANEOUS_SESSION'));
408
+ }
409
+ /**
410
+ * Set (or reset) the current user's device (by key) in the current project (stored in Cognito).
411
+ */
412
+ setCurrentDeviceForProject(deviceKey) {
413
+ const attributes = {};
414
+ // note: an empty string will remove the attribute from Cognito
415
+ attributes[DEVICE_KEY_ATTRIBUTE] = deviceKey || '';
416
+ return this.updateUserAttributes(attributes);
417
+ }
418
+ /**
419
+ * Update the currently logged in user's attributes.
420
+ */
421
+ updateUserAttributes(attributes) {
422
+ return new Promise((resolve, reject) => {
423
+ // prepare the attributes we want to change
424
+ const attrs = new Array();
425
+ for (const prop in attributes)
426
+ if (attributes[prop] !== undefined)
427
+ attrs.push(this.prepareUserAttribute(prop, attributes[prop]));
428
+ const user = this.userPool.getCurrentUser();
429
+ if (!user)
430
+ return reject();
431
+ // we need to get the session before to make changes
432
+ user.getSession((err) => {
433
+ if (err)
434
+ reject(err);
435
+ else
436
+ user.updateAttributes(attrs, (e) => (e ? reject(e) : resolve()));
437
+ });
438
+ });
439
+ }
440
+ /**
441
+ * Validate the password against the policy set in the environments configuration.
442
+ * In case there are errors, they are returned as an array of strings.
443
+ */
444
+ validatePasswordAgainstPolicy(password) {
445
+ const errors = [];
446
+ if (password?.trim().length < this.passwordPolicy.minLength)
447
+ errors.push('MIN_LENGTH');
448
+ if (this.passwordPolicy.requireDigits && !/\d/.test(password))
449
+ errors.push('REQUIRE_DIGITS');
450
+ if (this.passwordPolicy.requireLowercase && !/[a-z]/.test(password))
451
+ errors.push('REQUIRE_LOWERCASE');
452
+ if (this.passwordPolicy.requireSymbols && !/[\^\$\*\.\_\~\`\+\=@\!\?\>\<\:\;\\\,\#\%\&]/.test(password))
453
+ errors.push('REQUIRE_SYMBOLS');
454
+ if (this.passwordPolicy.requireUppercase && !/[A-Z]/.test(password))
455
+ errors.push('REQUIRE_UPPERCASE');
456
+ return errors;
457
+ }
458
+ /**
459
+ * Get a complete password policy pattern, based on the environments configuration, to use on password input fields.
460
+ * Note: some of the symbols couldn't be included because unsupported by the input[pattern] attribute.
461
+ */
462
+ getPasswordPolicyPatternForInput() {
463
+ let pattern = '';
464
+ if (this.passwordPolicy.requireDigits)
465
+ pattern += `(?=.*[0-9])`;
466
+ if (this.passwordPolicy.requireLowercase)
467
+ pattern += `(?=.*[a-z])`;
468
+ if (this.passwordPolicy.requireSymbols)
469
+ pattern += `(?=.*[\^\$\*\.\_\~\`\+\=@\!\?\>\<\:\;\\\,\#\%\&])`;
470
+ if (this.passwordPolicy.requireUppercase)
471
+ pattern += `(?=.*[A-Z])`;
472
+ pattern += `.{${this.passwordPolicy.minLength},}`;
473
+ return pattern;
474
+ }
475
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthService, deps: [{ token: i2.IDEAStorageService }], target: i0.ɵɵFactoryTarget.Injectable }); }
476
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthService, providedIn: 'root' }); }
477
+ }
478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthService, decorators: [{
479
+ type: Injectable,
480
+ args: [{ providedIn: 'root' }]
481
+ }], ctorParameters: function () { return [{ type: i2.IDEAStorageService }]; } });
482
+ /**
483
+ * The possible actions following a successful login.
484
+ */
485
+ var LoginOutcomeActions;
486
+ (function (LoginOutcomeActions) {
487
+ LoginOutcomeActions["NONE"] = "none";
488
+ LoginOutcomeActions["NEW_PASSWORD"] = "newPassword";
489
+ LoginOutcomeActions["MFA_CHALLENGE"] = "mfaChallenge";
490
+ LoginOutcomeActions["MFA_SETUP"] = "mfaSetup";
491
+ })(LoginOutcomeActions || (LoginOutcomeActions = {}));
492
+
493
+ class IDEASignInPage {
494
+ constructor(navCtrl, message, loading, t, auth) {
495
+ this.navCtrl = navCtrl;
496
+ this.message = message;
497
+ this.loading = loading;
498
+ this.t = t;
499
+ this.auth = auth;
500
+ this.title = environment.idea.app.title;
501
+ this.registrationPossible = environment.idea.auth.registrationIsPossible;
502
+ this.hasIntroPage = environment.idea.app.hasIntroPage;
503
+ this.website = environment.idea.website;
504
+ this.agreementsCheck = true;
505
+ this.newAccountRegistered = false;
506
+ this.darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
507
+ }
508
+ ionViewDidEnter() {
509
+ // manage the scenario in which we just created a new account (show a explanatory message: email must be confirmed)
510
+ this.newAccountRegistered = !!this.auth.getNewAccountJustRegistered();
511
+ if (this.newAccountRegistered)
512
+ this.email = this.auth.getNewAccountJustRegistered();
513
+ }
514
+ async login() {
515
+ if (!this.agreementsCheck)
516
+ return;
517
+ try {
518
+ this.errorMsg = null;
519
+ await this.loading.show();
520
+ const loginAction = await this.auth.login(this.email, this.password);
521
+ if (loginAction === LoginOutcomeActions.NEW_PASSWORD)
522
+ this.navCtrl.navigateForward(['auth', 'new-password']);
523
+ else if (loginAction === LoginOutcomeActions.MFA_CHALLENGE)
524
+ this.navCtrl.navigateForward(['auth', 'mfa-challenge']);
525
+ else if (loginAction === LoginOutcomeActions.MFA_SETUP)
526
+ this.navCtrl.navigateForward(['auth', 'setup-mfa']);
527
+ else
528
+ window.location.assign('');
529
+ }
530
+ catch (err) {
531
+ if (err.name === 'UserNotConfirmedException')
532
+ this.errorMsg = this.t._('IDEA_AUTH.CONFIRM_YOUR_EMAIL_TO_LOGIN');
533
+ else if (err.name === 'UserLambdaValidationException' &&
534
+ err.message?.includes('@IDEA_COGNITO_TRANSITION'))
535
+ this.errorMsg = this.t._('IDEA_AUTH.CHANGE_YOUR_PASSWORD_TO_LOGIN');
536
+ this.message.error('IDEA_AUTH.AUTHENTICATION_FAILED');
537
+ }
538
+ finally {
539
+ this.loading.hide();
540
+ }
541
+ }
542
+ goToIntro() {
543
+ this.navCtrl.navigateBack(['intro']);
544
+ }
545
+ goToForgotPassword() {
546
+ this.navCtrl.navigateForward(['auth/forgot-password']);
547
+ }
548
+ goToRegistration() {
549
+ this.navCtrl.navigateForward(['auth', 'sign-up']);
550
+ }
551
+ translationExists(key) {
552
+ return !!this.t._(key);
553
+ }
554
+ async openLink(url) {
555
+ await Browser.open({ url });
556
+ }
557
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASignInPage, deps: [{ token: i1.NavController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: i2.IDEATranslationsService }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
558
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEASignInPage, selector: "idea-sign-in", ngImport: i0, template: "<ion-content>\n <ion-card color=\"warning\" *ngIf=\"newAccountRegistered\">\n <ion-card-content>{{ 'IDEA_AUTH.CONFIRM_YOUR_EMAIL_TO_LOGIN' | translate }}</ion-card-content>\n </ion-card>\n <form class=\"flexBox\">\n <div>\n <ion-card class=\"authCard\">\n <ion-img\n [title]=\"'IDEA_AUTH.SERVICE_LOGO' | translate\"\n [src]=\"darkMode ? 'assets/icons/icon-auth-alt.svg' : 'assets/icons/icon-auth.svg'\"\n ></ion-img>\n <ion-card-header>\n <ion-card-title color=\"primary\" *ngIf=\"title\">{{ title }}</ion-card-title>\n <ion-card-subtitle *ngIf=\"translationExists('IDEA_VARIABLES.TAGLINE')\">\n {{ 'IDEA_VARIABLES.TAGLINE' | translate }}\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\"><b>{{ 'IDEA_AUTH.WARNING' | translate }}.</b> {{ errorMsg }}</p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"login()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n id=\"current-password\"\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"current-password\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.PASSWORD_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"password\"\n (keyup.enter)=\"login()\"\n ></ion-input>\n </ion-item>\n <ion-row\n class=\"agreementsAcceptanceRow\"\n *ngIf=\"\n !registrationPossible &&\n (translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL') || translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL'))\n \"\n >\n <ion-col>\n <ion-checkbox\n size=\"small\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"agreementsCheck\"\n ></ion-checkbox>\n {{ 'IDEA_AUTH.AGREEMENTS_CHECK_LOGIN' | translate }}:\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\"\n [title]=\"'IDEA_AUTH.TERMS_AND_CONDITIONS_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL' | translate\"\n >\n {{ 'IDEA_AUTH.TERMS_AND_CONDITIONS' | translate }}\n </a>\n <ion-text\n *ngIf=\"\n translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL') && translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\n \"\n >\n &\n </ion-text>\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL')\"\n [title]=\"'IDEA_AUTH.PRIVACY_POLICY_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.PRIVACY_POLICY_URL' | translate\"\n >\n {{ 'IDEA_AUTH.PRIVACY_POLICY' | translate }}\n </a>\n </ion-col>\n </ion-row>\n <ion-button\n expand=\"block\"\n [disabled]=\"!agreementsCheck\"\n [title]=\"'IDEA_AUTH.SIGN_IN_HINT' | translate\"\n (click)=\"login()\"\n >\n {{ 'IDEA_AUTH.SIGN_IN' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n *ngIf=\"registrationPossible\"\n [title]=\"'IDEA_AUTH.CREATE_AN_ACCOUNT_HINT' | translate\"\n (click)=\"goToRegistration()\"\n >\n {{ 'IDEA_AUTH.CREATE_AN_ACCOUNT' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.I_FORGOT_MY_PASSWORD_HINT' | translate\"\n (click)=\"goToForgotPassword()\"\n >\n {{ 'IDEA_AUTH.I_FORGOT_MY_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n color=\"medium\"\n class=\"smallCaseButton\"\n *ngIf=\"hasIntroPage\"\n [title]=\"'IDEA_AUTH.BACK_TO_INTRO_HINT' | translate\"\n (click)=\"goToIntro()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_INTRO' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n <ion-img\n class=\"ideaLogo\"\n *ngIf=\"website\"\n [src]=\"darkMode ? './assets/icons/idea-alt.png' : './assets/icons/idea.png'\"\n [title]=\"'IDEA_AUTH.IDEA_TAGLINE' | translate\"\n (click)=\"openLink(website)\"\n ></ion-img>\n </div>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "legacy", "mode", "name", "value"] }, { kind: "component", type: i1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonImg, selector: "ion-img", inputs: ["alt", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonRow, selector: "ion-row" }, { kind: "component", type: i1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
559
+ }
560
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASignInPage, decorators: [{
561
+ type: Component,
562
+ args: [{ selector: 'idea-sign-in', template: "<ion-content>\n <ion-card color=\"warning\" *ngIf=\"newAccountRegistered\">\n <ion-card-content>{{ 'IDEA_AUTH.CONFIRM_YOUR_EMAIL_TO_LOGIN' | translate }}</ion-card-content>\n </ion-card>\n <form class=\"flexBox\">\n <div>\n <ion-card class=\"authCard\">\n <ion-img\n [title]=\"'IDEA_AUTH.SERVICE_LOGO' | translate\"\n [src]=\"darkMode ? 'assets/icons/icon-auth-alt.svg' : 'assets/icons/icon-auth.svg'\"\n ></ion-img>\n <ion-card-header>\n <ion-card-title color=\"primary\" *ngIf=\"title\">{{ title }}</ion-card-title>\n <ion-card-subtitle *ngIf=\"translationExists('IDEA_VARIABLES.TAGLINE')\">\n {{ 'IDEA_VARIABLES.TAGLINE' | translate }}\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\"><b>{{ 'IDEA_AUTH.WARNING' | translate }}.</b> {{ errorMsg }}</p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"login()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n id=\"current-password\"\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"current-password\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.PASSWORD_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"password\"\n (keyup.enter)=\"login()\"\n ></ion-input>\n </ion-item>\n <ion-row\n class=\"agreementsAcceptanceRow\"\n *ngIf=\"\n !registrationPossible &&\n (translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL') || translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL'))\n \"\n >\n <ion-col>\n <ion-checkbox\n size=\"small\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"agreementsCheck\"\n ></ion-checkbox>\n {{ 'IDEA_AUTH.AGREEMENTS_CHECK_LOGIN' | translate }}:\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\"\n [title]=\"'IDEA_AUTH.TERMS_AND_CONDITIONS_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL' | translate\"\n >\n {{ 'IDEA_AUTH.TERMS_AND_CONDITIONS' | translate }}\n </a>\n <ion-text\n *ngIf=\"\n translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL') && translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\n \"\n >\n &\n </ion-text>\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL')\"\n [title]=\"'IDEA_AUTH.PRIVACY_POLICY_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.PRIVACY_POLICY_URL' | translate\"\n >\n {{ 'IDEA_AUTH.PRIVACY_POLICY' | translate }}\n </a>\n </ion-col>\n </ion-row>\n <ion-button\n expand=\"block\"\n [disabled]=\"!agreementsCheck\"\n [title]=\"'IDEA_AUTH.SIGN_IN_HINT' | translate\"\n (click)=\"login()\"\n >\n {{ 'IDEA_AUTH.SIGN_IN' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n *ngIf=\"registrationPossible\"\n [title]=\"'IDEA_AUTH.CREATE_AN_ACCOUNT_HINT' | translate\"\n (click)=\"goToRegistration()\"\n >\n {{ 'IDEA_AUTH.CREATE_AN_ACCOUNT' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.I_FORGOT_MY_PASSWORD_HINT' | translate\"\n (click)=\"goToForgotPassword()\"\n >\n {{ 'IDEA_AUTH.I_FORGOT_MY_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n color=\"medium\"\n class=\"smallCaseButton\"\n *ngIf=\"hasIntroPage\"\n [title]=\"'IDEA_AUTH.BACK_TO_INTRO_HINT' | translate\"\n (click)=\"goToIntro()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_INTRO' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n <ion-img\n class=\"ideaLogo\"\n *ngIf=\"website\"\n [src]=\"darkMode ? './assets/icons/idea-alt.png' : './assets/icons/idea.png'\"\n [title]=\"'IDEA_AUTH.IDEA_TAGLINE' | translate\"\n (click)=\"openLink(website)\"\n ></ion-img>\n </div>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
563
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: i2.IDEATranslationsService }, { type: IDEAAuthService }]; } });
564
+
565
+ class IDEAPasswordPolicyComponent {
566
+ constructor() {
567
+ this.passwordPolicy = environment.idea.auth.passwordPolicy;
568
+ }
569
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAPasswordPolicyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
570
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEAPasswordPolicyComponent, selector: "idea-password-policy", ngImport: i0, template: `
571
+ <ion-card class="passwordPolicyCard">
572
+ <ion-card-header>
573
+ <ion-card-title>{{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS_TITLE' | translate }}</ion-card-title>
574
+ </ion-card-header>
575
+ <ion-card-content>
576
+ <ul>
577
+ <li>{{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.MIN_LENGTH' | translate : { n: passwordPolicy.minLength } }}</li>
578
+ <li *ngIf="passwordPolicy.requireDigits">
579
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_DIGITS' | translate }}
580
+ </li>
581
+ <li *ngIf="passwordPolicy.requireSymbols">
582
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_SYMBOLS' | translate }}
583
+ </li>
584
+ <li *ngIf="passwordPolicy.requireUppercase">
585
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_UPPERCASE' | translate }}
586
+ </li>
587
+ <li *ngIf="passwordPolicy.requireLowercase">
588
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_LOWERCASE' | translate }}
589
+ </li>
590
+ </ul>
591
+ </ion-card-content>
592
+ </ion-card>
593
+ `, isInline: true, styles: ["ion-card.passwordPolicyCard{box-shadow:none;border:none;padding:6px}ion-card.passwordPolicyCard ion-card-title{font-size:1rem}ion-card.passwordPolicyCard ul{margin:0}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
594
+ }
595
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAPasswordPolicyComponent, decorators: [{
596
+ type: Component,
597
+ args: [{ selector: 'idea-password-policy', template: `
598
+ <ion-card class="passwordPolicyCard">
599
+ <ion-card-header>
600
+ <ion-card-title>{{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS_TITLE' | translate }}</ion-card-title>
601
+ </ion-card-header>
602
+ <ion-card-content>
603
+ <ul>
604
+ <li>{{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.MIN_LENGTH' | translate : { n: passwordPolicy.minLength } }}</li>
605
+ <li *ngIf="passwordPolicy.requireDigits">
606
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_DIGITS' | translate }}
607
+ </li>
608
+ <li *ngIf="passwordPolicy.requireSymbols">
609
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_SYMBOLS' | translate }}
610
+ </li>
611
+ <li *ngIf="passwordPolicy.requireUppercase">
612
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_UPPERCASE' | translate }}
613
+ </li>
614
+ <li *ngIf="passwordPolicy.requireLowercase">
615
+ {{ 'IDEA_AUTH.PASSWORD_REQUIREMENTS.REQUIRE_LOWERCASE' | translate }}
616
+ </li>
617
+ </ul>
618
+ </ion-card-content>
619
+ </ion-card>
620
+ `, styles: ["ion-card.passwordPolicyCard{box-shadow:none;border:none;padding:6px}ion-card.passwordPolicyCard ion-card-title{font-size:1rem}ion-card.passwordPolicyCard ul{margin:0}\n"] }]
621
+ }], ctorParameters: function () { return []; } });
622
+
623
+ class IDEASignUpPage {
624
+ constructor(navCtrl, popoverCtrl, message, loading, t, auth) {
625
+ this.navCtrl = navCtrl;
626
+ this.popoverCtrl = popoverCtrl;
627
+ this.message = message;
628
+ this.loading = loading;
629
+ this.t = t;
630
+ this.auth = auth;
631
+ this.agreementsCheck = false;
632
+ this.passwordPolicy = environment.idea.auth.passwordPolicy;
633
+ }
634
+ ngOnInit() {
635
+ if (!environment.idea.auth.registrationIsPossible)
636
+ return this.goToAuth();
637
+ this.agreementsCheck =
638
+ this.t._('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL') || this.t._('IDEA_VARIABLES.PRIVACY_POLICY_URL')
639
+ ? this.agreementsCheck
640
+ : true;
641
+ }
642
+ async register() {
643
+ this.errorMsg = null;
644
+ if (isEmpty(this.email, 'email'))
645
+ this.errorMsg = this.t._('IDEA_AUTH.VALID_EMAIL_OBLIGATORY');
646
+ else {
647
+ const errors = this.auth.validatePasswordAgainstPolicy(this.password);
648
+ if (errors.length)
649
+ this.errorMsg = [
650
+ this.t._('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW'),
651
+ ...errors.map(x => this.t._('IDEA_AUTH.PASSWORD_REQUIREMENTS.'.concat(x), { n: this.passwordPolicy.minLength }))
652
+ ].join(' ');
653
+ }
654
+ if (this.errorMsg)
655
+ return this.message.error('IDEA_AUTH.REGISTRATION_FAILED');
656
+ try {
657
+ await this.loading.show();
658
+ await this.auth.register(this.email, this.password);
659
+ this.message.success('IDEA_AUTH.REGISTRATION_COMPLETED');
660
+ this.goToAuth();
661
+ }
662
+ catch (err) {
663
+ this.errorMsg = err.message;
664
+ this.message.error('IDEA_AUTH.REGISTRATION_FAILED');
665
+ }
666
+ finally {
667
+ this.loading.hide();
668
+ }
669
+ }
670
+ translationExists(key) {
671
+ return !!this.t._(key);
672
+ }
673
+ async openPasswordPolicy(event) {
674
+ const cssClass = 'passwordPolicyPopover';
675
+ const popover = await this.popoverCtrl.create({ component: IDEAPasswordPolicyComponent, event, cssClass });
676
+ await popover.present();
677
+ }
678
+ goToResendLink() {
679
+ this.navCtrl.navigateForward(['auth/resend-link']);
680
+ }
681
+ goToAuth() {
682
+ this.navCtrl.navigateBack(['auth']);
683
+ }
684
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASignUpPage, deps: [{ token: i1.NavController }, { token: i1.PopoverController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: i2.IDEATranslationsService }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
685
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEASignUpPage, selector: "idea-sign-up", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.NEW_ACCOUNT' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.REGISTER_A_NEW_ACCOUNT_TO_THE_SYSTEM' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.REGISTRATION_EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"register()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n [pattern]=\"auth.getPasswordPolicyPatternForInput()\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"password\"\n (keyup.enter)=\"register()\"\n ></ion-input>\n <ion-button slot=\"end\" fill=\"clear\" color=\"dark\" (click)=\"openPasswordPolicy($event)\">\n <ion-icon icon=\"help-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-item>\n <ion-row\n class=\"agreementsAcceptanceRow\"\n *ngIf=\"translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL') || translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL')\"\n >\n <ion-col>\n <ion-checkbox\n size=\"small\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"agreementsCheck\"\n ></ion-checkbox>\n {{ 'IDEA_AUTH.AGREEMENTS_CHECK_REGISTRATION' | translate }}:\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\"\n [title]=\"'IDEA_AUTH.TERMS_AND_CONDITIONS_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL' | translate\"\n >\n {{ 'IDEA_AUTH.TERMS_AND_CONDITIONS' | translate }}\n </a>\n <ion-text\n *ngIf=\"\n translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL') && translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\n \"\n >\n &\n </ion-text>\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL')\"\n [title]=\"'IDEA_AUTH.PRIVACY_POLICY_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.PRIVACY_POLICY_URL' | translate\"\n >\n {{ 'IDEA_AUTH.PRIVACY_POLICY' | translate }}\n </a>\n </ion-col>\n </ion-row>\n <ion-button\n expand=\"block\"\n [disabled]=\"!agreementsCheck\"\n [title]=\"'IDEA_AUTH.CREATE_AN_ACCOUNT_HINT' | translate\"\n (click)=\"register()\"\n >\n {{ 'IDEA_AUTH.CREATE_AN_ACCOUNT' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.HAVEN_T_RECEIVED_CONFIRMATION_LINK_HINT' | translate\"\n (click)=\"goToResendLink()\"\n >\n {{ 'IDEA_AUTH.HAVEN_T_RECEIVED_CONFIRMATION_LINK' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "legacy", "mode", "name", "value"] }, { kind: "component", type: i1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonRow, selector: "ion-row" }, { kind: "component", type: i1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
686
+ }
687
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASignUpPage, decorators: [{
688
+ type: Component,
689
+ args: [{ selector: 'idea-sign-up', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.NEW_ACCOUNT' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.REGISTER_A_NEW_ACCOUNT_TO_THE_SYSTEM' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.REGISTRATION_EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"register()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n [pattern]=\"auth.getPasswordPolicyPatternForInput()\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"password\"\n (keyup.enter)=\"register()\"\n ></ion-input>\n <ion-button slot=\"end\" fill=\"clear\" color=\"dark\" (click)=\"openPasswordPolicy($event)\">\n <ion-icon icon=\"help-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-item>\n <ion-row\n class=\"agreementsAcceptanceRow\"\n *ngIf=\"translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL') || translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL')\"\n >\n <ion-col>\n <ion-checkbox\n size=\"small\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"agreementsCheck\"\n ></ion-checkbox>\n {{ 'IDEA_AUTH.AGREEMENTS_CHECK_REGISTRATION' | translate }}:\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\"\n [title]=\"'IDEA_AUTH.TERMS_AND_CONDITIONS_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL' | translate\"\n >\n {{ 'IDEA_AUTH.TERMS_AND_CONDITIONS' | translate }}\n </a>\n <ion-text\n *ngIf=\"\n translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL') && translationExists('IDEA_VARIABLES.TERMS_AND_CONDITIONS_URL')\n \"\n >\n &\n </ion-text>\n <a\n ion-text\n color=\"primary\"\n target=\"_blank\"\n *ngIf=\"translationExists('IDEA_VARIABLES.PRIVACY_POLICY_URL')\"\n [title]=\"'IDEA_AUTH.PRIVACY_POLICY_HINT' | translate\"\n [href]=\"'IDEA_VARIABLES.PRIVACY_POLICY_URL' | translate\"\n >\n {{ 'IDEA_AUTH.PRIVACY_POLICY' | translate }}\n </a>\n </ion-col>\n </ion-row>\n <ion-button\n expand=\"block\"\n [disabled]=\"!agreementsCheck\"\n [title]=\"'IDEA_AUTH.CREATE_AN_ACCOUNT_HINT' | translate\"\n (click)=\"register()\"\n >\n {{ 'IDEA_AUTH.CREATE_AN_ACCOUNT' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.HAVEN_T_RECEIVED_CONFIRMATION_LINK_HINT' | translate\"\n (click)=\"goToResendLink()\"\n >\n {{ 'IDEA_AUTH.HAVEN_T_RECEIVED_CONFIRMATION_LINK' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
690
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i1.PopoverController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: i2.IDEATranslationsService }, { type: IDEAAuthService }]; } });
691
+
692
+ class IDEANewPasswordPage {
693
+ constructor(navCtrl, popoverCtrl, message, loading, t, auth) {
694
+ this.navCtrl = navCtrl;
695
+ this.popoverCtrl = popoverCtrl;
696
+ this.message = message;
697
+ this.loading = loading;
698
+ this.t = t;
699
+ this.auth = auth;
700
+ this.passwordPolicy = environment.idea.auth.passwordPolicy;
701
+ }
702
+ ngOnInit() {
703
+ if (!this.auth.challengeUsername)
704
+ this.goToAuth();
705
+ }
706
+ async confirmNewPassword() {
707
+ try {
708
+ this.errorMsg = null;
709
+ const errors = this.auth.validatePasswordAgainstPolicy(this.newPassword);
710
+ if (errors.length)
711
+ this.errorMsg = [
712
+ this.t._('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW'),
713
+ ...errors.map(x => this.t._('IDEA_AUTH.PASSWORD_REQUIREMENTS.'.concat(x), { n: this.passwordPolicy.minLength }))
714
+ ].join(' ');
715
+ if (this.errorMsg)
716
+ return this.message.error('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW');
717
+ await this.loading.show();
718
+ await this.auth.confirmNewPassword(this.newPassword);
719
+ window.location.assign('');
720
+ }
721
+ catch (error) {
722
+ this.errorMsg = error.message;
723
+ this.message.error('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW');
724
+ }
725
+ finally {
726
+ this.loading.hide();
727
+ }
728
+ }
729
+ async openPasswordPolicy(event) {
730
+ const cssClass = 'passwordPolicyPopover';
731
+ const popover = await this.popoverCtrl.create({ component: IDEAPasswordPolicyComponent, event, cssClass });
732
+ await popover.present();
733
+ }
734
+ goToAuth() {
735
+ this.navCtrl.navigateBack(['auth']);
736
+ }
737
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEANewPasswordPage, deps: [{ token: i1.NavController }, { token: i1.PopoverController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: i2.IDEATranslationsService }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
738
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEANewPasswordPage, selector: "idea-new-password", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.YOU_NEED_TO_CHOOSE_A_NEW_PASSWORD' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"new-password\"\n [pattern]=\"auth.getPasswordPolicyPatternForInput()\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"newPassword\"\n (keyup.enter)=\"confirmNewPassword()\"\n ></ion-input>\n <ion-button slot=\"end\" fill=\"clear\" color=\"dark\" (click)=\"openPasswordPolicy($event)\">\n <ion-icon icon=\"help-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.CONFIRM_NEW_PASSWORD_HINT' | translate\"\n (click)=\"confirmNewPassword()\"\n >\n {{ 'IDEA_AUTH.CONFIRM_NEW_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
739
+ }
740
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEANewPasswordPage, decorators: [{
741
+ type: Component,
742
+ args: [{ selector: 'idea-new-password', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.YOU_NEED_TO_CHOOSE_A_NEW_PASSWORD' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"new-password\"\n [pattern]=\"auth.getPasswordPolicyPatternForInput()\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"newPassword\"\n (keyup.enter)=\"confirmNewPassword()\"\n ></ion-input>\n <ion-button slot=\"end\" fill=\"clear\" color=\"dark\" (click)=\"openPasswordPolicy($event)\">\n <ion-icon icon=\"help-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.CONFIRM_NEW_PASSWORD_HINT' | translate\"\n (click)=\"confirmNewPassword()\"\n >\n {{ 'IDEA_AUTH.CONFIRM_NEW_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
743
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i1.PopoverController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: i2.IDEATranslationsService }, { type: IDEAAuthService }]; } });
744
+
745
+ class IDEAResendLinkPage {
746
+ constructor(navCtrl, message, loading, auth, t) {
747
+ this.navCtrl = navCtrl;
748
+ this.message = message;
749
+ this.loading = loading;
750
+ this.auth = auth;
751
+ this.t = t;
752
+ }
753
+ async resendConfirmationLink() {
754
+ this.errorMsg = null;
755
+ if (!this.email) {
756
+ this.errorMsg = this.t._('IDEA_AUTH.VALID_EMAIL_OBLIGATORY');
757
+ this.message.error('IDEA_AUTH.SENDING_FAILED');
758
+ return;
759
+ }
760
+ try {
761
+ await this.loading.show();
762
+ await this.auth.resendConfirmationCode(this.email);
763
+ this.message.success('IDEA_AUTH.CONFIRMATION_LINK_SENT');
764
+ this.goToAuth();
765
+ }
766
+ catch (error) {
767
+ this.errorMsg = this.t._('IDEA_AUTH.IS_THE_EMAIL_CORRECT');
768
+ this.message.error('IDEA_AUTH.SENDING_FAILED');
769
+ }
770
+ finally {
771
+ this.loading.hide();
772
+ }
773
+ }
774
+ goToAuth() {
775
+ this.navCtrl.navigateBack(['auth']);
776
+ }
777
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAResendLinkPage, deps: [{ token: i1.NavController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: IDEAAuthService }, { token: i2.IDEATranslationsService }], target: i0.ɵɵFactoryTarget.Component }); }
778
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEAResendLinkPage, selector: "idea-resend-link", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.CONFIRM_ACCOUNT' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.RESEND_CONFIRMATION_LINK_HINT' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"resendConfirmationLink()\"\n ></ion-input>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.RESEND_LINK_HINT' | translate\"\n (click)=\"resendConfirmationLink()\"\n >\n {{ 'IDEA_AUTH.RESEND_LINK' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
779
+ }
780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAResendLinkPage, decorators: [{
781
+ type: Component,
782
+ args: [{ selector: 'idea-resend-link', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.CONFIRM_ACCOUNT' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.RESEND_CONFIRMATION_LINK_HINT' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"resendConfirmationLink()\"\n ></ion-input>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.RESEND_LINK_HINT' | translate\"\n (click)=\"resendConfirmationLink()\"\n >\n {{ 'IDEA_AUTH.RESEND_LINK' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
783
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: IDEAAuthService }, { type: i2.IDEATranslationsService }]; } });
784
+
785
+ class IDEAForgotPasswordPage {
786
+ constructor(navCtrl, message, loading, auth) {
787
+ this.navCtrl = navCtrl;
788
+ this.message = message;
789
+ this.loading = loading;
790
+ this.auth = auth;
791
+ }
792
+ async forgotPassword() {
793
+ try {
794
+ await this.loading.show();
795
+ await this.auth.forgotPassword(this.email);
796
+ this.message.success('IDEA_AUTH.PASSWORD_RESET_CODE_SENT');
797
+ this.goToConfirmPassword();
798
+ }
799
+ catch (error) {
800
+ this.message.error('IDEA_AUTH.USER_NOT_FOUND');
801
+ }
802
+ finally {
803
+ this.loading.hide();
804
+ }
805
+ }
806
+ goToConfirmPassword() {
807
+ this.navCtrl.navigateForward(['auth/confirm-password'], { queryParams: { email: this.email ?? null } });
808
+ }
809
+ goToAuth() {
810
+ this.navCtrl.navigateBack(['auth']);
811
+ }
812
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAForgotPasswordPage, deps: [{ token: i1.NavController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
813
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEAForgotPasswordPage, selector: "idea-forgot-password", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.PASSWORD_RESET' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.PASSWORD_RESET_HINT' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"forgotPassword()\"\n ></ion-input>\n </ion-item>\n <ion-button expand=\"block\" [title]=\"'IDEA_AUTH.RESET_MY_PASSWORD_HINT' | translate\" (click)=\"forgotPassword()\">\n {{ 'IDEA_AUTH.RESET_MY_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.ALREADY_HAVE_A_RESET_CODE_HINT' | translate\"\n (click)=\"goToConfirmPassword()\"\n >\n {{ 'IDEA_AUTH.ALREADY_HAVE_A_RESET_CODE' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
814
+ }
815
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAForgotPasswordPage, decorators: [{
816
+ type: Component,
817
+ args: [{ selector: 'idea-forgot-password', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.PASSWORD_RESET' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.PASSWORD_RESET_HINT' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"forgotPassword()\"\n ></ion-input>\n </ion-item>\n <ion-button expand=\"block\" [title]=\"'IDEA_AUTH.RESET_MY_PASSWORD_HINT' | translate\" (click)=\"forgotPassword()\">\n {{ 'IDEA_AUTH.RESET_MY_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.ALREADY_HAVE_A_RESET_CODE_HINT' | translate\"\n (click)=\"goToConfirmPassword()\"\n >\n {{ 'IDEA_AUTH.ALREADY_HAVE_A_RESET_CODE' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
818
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: IDEAAuthService }]; } });
819
+
820
+ class IDEAConfirmPasswordPage {
821
+ constructor(navCtrl, route, popoverCtrl, message, loading, t, auth) {
822
+ this.navCtrl = navCtrl;
823
+ this.route = route;
824
+ this.popoverCtrl = popoverCtrl;
825
+ this.message = message;
826
+ this.loading = loading;
827
+ this.t = t;
828
+ this.auth = auth;
829
+ this.passwordPolicy = environment.idea.auth.passwordPolicy;
830
+ }
831
+ ngOnInit() {
832
+ this.email = this.route.snapshot.queryParamMap.get('email') ?? null;
833
+ if (!this.email && this.route.snapshot.queryParams.user)
834
+ this.email = decodeURIComponent(this.route.snapshot.queryParams.user);
835
+ this.code = this.route.snapshot.queryParams.code;
836
+ }
837
+ async confirmPassword() {
838
+ try {
839
+ this.errorMsg = null;
840
+ const errors = this.auth.validatePasswordAgainstPolicy(this.newPassword);
841
+ if (errors.length)
842
+ this.errorMsg = [
843
+ this.t._('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW'),
844
+ ...errors.map(x => this.t._('IDEA_AUTH.PASSWORD_REQUIREMENTS.'.concat(x), { n: this.passwordPolicy.minLength }))
845
+ ].join(' ');
846
+ if (this.errorMsg)
847
+ return this.message.error('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW');
848
+ await this.loading.show();
849
+ await this.auth.confirmPassword(this.email, this.code, this.newPassword);
850
+ this.message.success('IDEA_AUTH.PASSWORD_CHANGED');
851
+ this.goToAuth();
852
+ }
853
+ catch (error) {
854
+ this.errorMsg = error.message;
855
+ this.message.error('IDEA_AUTH.PASSWORD_REQUIREMENTS_FOLLOW');
856
+ }
857
+ finally {
858
+ this.loading.hide();
859
+ }
860
+ }
861
+ async openPasswordPolicy(event) {
862
+ const cssClass = 'passwordPolicyPopover';
863
+ const popover = await this.popoverCtrl.create({ component: IDEAPasswordPolicyComponent, event, cssClass });
864
+ await popover.present();
865
+ }
866
+ goToForgotPassword() {
867
+ this.navCtrl.navigateBack(['auth/forgot-password']);
868
+ }
869
+ goToAuth() {
870
+ this.navCtrl.navigateBack(['auth']);
871
+ }
872
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAConfirmPasswordPage, deps: [{ token: i1.NavController }, { token: i2$1.ActivatedRoute }, { token: i1.PopoverController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: i2.IDEATranslationsService }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
873
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEAConfirmPasswordPage, selector: "idea-confirm-password", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.CHANGE_THE_PASSWORD' | translate }}</ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"confirmPassword()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"disc\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"text\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n [placeholder]=\"'IDEA_AUTH.RESET_CODE' | translate\"\n [title]=\"'IDEA_AUTH.RESET_CODE_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"code\"\n (keyup.enter)=\"confirmPassword()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"new-password\"\n [pattern]=\"auth.getPasswordPolicyPatternForInput()\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.NEW_PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"newPassword\"\n (keyup.enter)=\"confirmPassword()\"\n ></ion-input>\n <ion-button slot=\"end\" fill=\"clear\" color=\"dark\" (click)=\"openPasswordPolicy($event)\">\n <ion-icon icon=\"help-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.CHANGE_MY_PASSWORD_HINT' | translate\"\n (click)=\"confirmPassword()\"\n >\n {{ 'IDEA_AUTH.CHANGE_MY_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.HAVEN_T_RECEIVED_A_RESET_CODE_HINT' | translate\"\n (click)=\"goToForgotPassword()\"\n >\n {{ 'IDEA_AUTH.HAVEN_T_RECEIVED_A_RESET_CODE' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
874
+ }
875
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAConfirmPasswordPage, decorators: [{
876
+ type: Component,
877
+ args: [{ selector: 'idea-confirm-password', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.CHANGE_THE_PASSWORD' | translate }}</ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b> {{ 'IDEA_AUTH.ERROR' | translate }}. </b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"person-circle\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"email\"\n inputmode=\"email\"\n pattern=\"[A-Za-z0-9._%+-]{2,}@[a-zA-Z-_.]{2,}[.]{1}[a-zA-Z]{2,}\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"email\"\n [placeholder]=\"'IDEA_AUTH.EMAIL' | translate\"\n [title]=\"'IDEA_AUTH.EMAIL_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"email\"\n (keyup.enter)=\"confirmPassword()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"disc\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"text\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"off\"\n [placeholder]=\"'IDEA_AUTH.RESET_CODE' | translate\"\n [title]=\"'IDEA_AUTH.RESET_CODE_HINT' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"code\"\n (keyup.enter)=\"confirmPassword()\"\n ></ion-input>\n </ion-item>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n type=\"password\"\n spellcheck=\"false\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n autocomplete=\"new-password\"\n [pattern]=\"auth.getPasswordPolicyPatternForInput()\"\n [clearOnEdit]=\"false\"\n [placeholder]=\"'IDEA_AUTH.NEW_PASSWORD' | translate\"\n [title]=\"'IDEA_AUTH.CHOOSE_A_PASSWORD' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"newPassword\"\n (keyup.enter)=\"confirmPassword()\"\n ></ion-input>\n <ion-button slot=\"end\" fill=\"clear\" color=\"dark\" (click)=\"openPasswordPolicy($event)\">\n <ion-icon icon=\"help-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.CHANGE_MY_PASSWORD_HINT' | translate\"\n (click)=\"confirmPassword()\"\n >\n {{ 'IDEA_AUTH.CHANGE_MY_PASSWORD' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.HAVEN_T_RECEIVED_A_RESET_CODE_HINT' | translate\"\n (click)=\"goToForgotPassword()\"\n >\n {{ 'IDEA_AUTH.HAVEN_T_RECEIVED_A_RESET_CODE' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
878
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i2$1.ActivatedRoute }, { type: i1.PopoverController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: i2.IDEATranslationsService }, { type: IDEAAuthService }]; } });
879
+
880
+ class IDEAMFAChallengePage {
881
+ constructor(navCtrl, message, loading, auth, t) {
882
+ this.navCtrl = navCtrl;
883
+ this.message = message;
884
+ this.loading = loading;
885
+ this.auth = auth;
886
+ this.t = t;
887
+ }
888
+ ngOnInit() {
889
+ if (!this.auth.challengeUsername)
890
+ this.goToAuth();
891
+ }
892
+ async completeMFAChallenge() {
893
+ try {
894
+ this.errorMsg = null;
895
+ await this.loading.show();
896
+ await this.auth.completeMFAChallenge(this.otpCode);
897
+ window.location.assign('');
898
+ }
899
+ catch (error) {
900
+ this.errorMsg = this.t._('IDEA_AUTH.INVALID_OTP_CODE');
901
+ this.message.error(this.errorMsg, true);
902
+ }
903
+ finally {
904
+ this.loading.hide();
905
+ }
906
+ }
907
+ goToAuth() {
908
+ this.navCtrl.navigateBack(['auth']);
909
+ }
910
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAMFAChallengePage, deps: [{ token: i1.NavController }, { token: i2.IDEAMessageService }, { token: i2.IDEALoadingService }, { token: IDEAAuthService }, { token: i2.IDEATranslationsService }], target: i0.ɵɵFactoryTarget.Component }); }
911
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEAMFAChallengePage, selector: "idea-mfa-challenge", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.ENTER_OTP_CODE' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.ENTER_OTP_CODE_I' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b>{{ 'IDEA_AUTH.ERROR' | translate }}.</b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n inputmode=\"numeric\"\n [placeholder]=\"'IDEA_AUTH.OTP_CODE' | translate\"\n [title]=\"'IDEA_AUTH.ENTER_OTP_CODE' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"otpCode\"\n (keyup.enter)=\"completeMFAChallenge()\"\n ></ion-input>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.CONFIRM_OTP_CODE_HINT' | translate\"\n (click)=\"completeMFAChallenge()\"\n >\n {{ 'IDEA_AUTH.CONFIRM_OTP_CODE' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
912
+ }
913
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAMFAChallengePage, decorators: [{
914
+ type: Component,
915
+ args: [{ selector: 'idea-mfa-challenge', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.ENTER_OTP_CODE' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.ENTER_OTP_CODE_I' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <p class=\"errorBox\" *ngIf=\"errorMsg\">\n <b>{{ 'IDEA_AUTH.ERROR' | translate }}.</b>\n {{ errorMsg }}\n </p>\n <ion-item>\n <ion-label position=\"inline\">\n <ion-icon name=\"key\" color=\"primary\"></ion-icon>\n </ion-label>\n <ion-input\n inputmode=\"numeric\"\n [placeholder]=\"'IDEA_AUTH.OTP_CODE' | translate\"\n [title]=\"'IDEA_AUTH.ENTER_OTP_CODE' | translate\"\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"otpCode\"\n (keyup.enter)=\"completeMFAChallenge()\"\n ></ion-input>\n </ion-item>\n <ion-button\n expand=\"block\"\n [title]=\"'IDEA_AUTH.CONFIRM_OTP_CODE_HINT' | translate\"\n (click)=\"completeMFAChallenge()\"\n >\n {{ 'IDEA_AUTH.CONFIRM_OTP_CODE' | translate }}\n </ion-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
916
+ }], ctorParameters: function () { return [{ type: i1.NavController }, { type: i2.IDEAMessageService }, { type: i2.IDEALoadingService }, { type: IDEAAuthService }, { type: i2.IDEATranslationsService }]; } });
917
+
918
+ class IDEASetupMFAModalComponent {
919
+ constructor(modalCtrl, loading, message, auth) {
920
+ this.modalCtrl = modalCtrl;
921
+ this.loading = loading;
922
+ this.message = message;
923
+ this.auth = auth;
924
+ }
925
+ async ngOnInit() {
926
+ try {
927
+ await this.loading.show();
928
+ this.isMFAEnabled = await this.auth.checkIfUserHasMFAEnabled(true);
929
+ if (!this.isMFAEnabled) {
930
+ const url = await this.auth.getURLForEnablingMFA();
931
+ await this.generateQRCodeCanvasByURL(url);
932
+ }
933
+ }
934
+ catch (error) {
935
+ this.message.error('COMMON.OPERATION_FAILED');
936
+ }
937
+ finally {
938
+ this.loading.hide();
939
+ }
940
+ }
941
+ generateQRCodeCanvasByURL(url) {
942
+ return new Promise((resolve, reject) => {
943
+ const container = document.getElementById('qrCodeContainer');
944
+ container.innerHTML = '';
945
+ toCanvas(url, { errorCorrectionLevel: 'L' }, (err, canvas) => {
946
+ if (err)
947
+ return reject(err);
948
+ canvas.style.width = '100%';
949
+ canvas.style.height = '100%';
950
+ canvas.style.borderRadius = '4px';
951
+ container.appendChild(canvas);
952
+ resolve();
953
+ });
954
+ });
955
+ }
956
+ async setMFA(enable) {
957
+ if (!this.otpCode)
958
+ return;
959
+ try {
960
+ await this.loading.show();
961
+ if (enable)
962
+ await this.auth.enableMFA(this.otpCode);
963
+ else
964
+ await this.auth.disableMFA(this.otpCode);
965
+ this.isMFAEnabled = enable;
966
+ this.message.success('COMMON.OPERATION_COMPLETED');
967
+ this.modalCtrl.dismiss({ enabled: enable });
968
+ }
969
+ catch (error) {
970
+ this.message.error('COMMON.OPERATION_FAILED');
971
+ }
972
+ finally {
973
+ this.loading.hide();
974
+ }
975
+ }
976
+ close() {
977
+ this.modalCtrl.dismiss();
978
+ }
979
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAModalComponent, deps: [{ token: i1.ModalController }, { token: i2.IDEALoadingService }, { token: i2.IDEAMessageService }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
980
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEASetupMFAModalComponent, selector: "idea-setup-mfa-modal", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n <ion-button [title]=\"'COMMON.CLOSE' | translate\" (click)=\"close()\">\n <ion-icon name=\"close-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-buttons>\n <ion-title>{{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA' : 'IDEA_AUTH.SETUP_MFA') | translate }}</ion-title>\n </ion-toolbar>\n</ion-header>\n<ion-content class=\"ion-padding\">\n <ion-list class=\"aList\">\n <ion-list-header>\n <ion-label class=\"ion-text-center\">\n <h2>{{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA_I' : 'IDEA_AUTH.SETUP_MFA_I') | translate }}</h2>\n <p>{{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA_II' : 'IDEA_AUTH.SETUP_MFA_II') | translate }}</p>\n </ion-label>\n </ion-list-header>\n <ion-card color=\"white\">\n <ion-card-content>\n <div id=\"qrCodeContainer\" *ngIf=\"!isMFAEnabled\"></div>\n <ion-item color=\"light\">\n <ion-label position=\"floating\">{{ 'IDEA_AUTH.OTP_CODE' | translate }}</ion-label>\n <ion-input type=\"text\" inputmode=\"numeric\" [(ngModel)]=\"otpCode\"></ion-input>\n </ion-item>\n <ion-button expand=\"block\" class=\"ion-margin-top\" [disabled]=\"!otpCode\" (click)=\"setMFA(!isMFAEnabled)\">\n {{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA' : 'IDEA_AUTH.ENABLE_MFA') | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </ion-list>\n</ion-content>\n", styles: ["ion-list.aList{padding-top:0}ion-list.aList ion-card{margin:10px auto;max-width:300px}ion-list.aList #qrCodeContainer{width:180px;margin:10px auto}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i1.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
981
+ }
982
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAModalComponent, decorators: [{
983
+ type: Component,
984
+ args: [{ selector: 'idea-setup-mfa-modal', template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n <ion-button [title]=\"'COMMON.CLOSE' | translate\" (click)=\"close()\">\n <ion-icon name=\"close-circle-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-buttons>\n <ion-title>{{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA' : 'IDEA_AUTH.SETUP_MFA') | translate }}</ion-title>\n </ion-toolbar>\n</ion-header>\n<ion-content class=\"ion-padding\">\n <ion-list class=\"aList\">\n <ion-list-header>\n <ion-label class=\"ion-text-center\">\n <h2>{{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA_I' : 'IDEA_AUTH.SETUP_MFA_I') | translate }}</h2>\n <p>{{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA_II' : 'IDEA_AUTH.SETUP_MFA_II') | translate }}</p>\n </ion-label>\n </ion-list-header>\n <ion-card color=\"white\">\n <ion-card-content>\n <div id=\"qrCodeContainer\" *ngIf=\"!isMFAEnabled\"></div>\n <ion-item color=\"light\">\n <ion-label position=\"floating\">{{ 'IDEA_AUTH.OTP_CODE' | translate }}</ion-label>\n <ion-input type=\"text\" inputmode=\"numeric\" [(ngModel)]=\"otpCode\"></ion-input>\n </ion-item>\n <ion-button expand=\"block\" class=\"ion-margin-top\" [disabled]=\"!otpCode\" (click)=\"setMFA(!isMFAEnabled)\">\n {{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA' : 'IDEA_AUTH.ENABLE_MFA') | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </ion-list>\n</ion-content>\n", styles: ["ion-list.aList{padding-top:0}ion-list.aList ion-card{margin:10px auto;max-width:300px}ion-list.aList #qrCodeContainer{width:180px;margin:10px auto}\n"] }]
985
+ }], ctorParameters: function () { return [{ type: i1.ModalController }, { type: i2.IDEALoadingService }, { type: i2.IDEAMessageService }, { type: IDEAAuthService }]; } });
986
+
987
+ class IDEASetupMFAButtonComponent {
988
+ constructor(modalCtrl, auth) {
989
+ this.modalCtrl = modalCtrl;
990
+ this.auth = auth;
991
+ /**
992
+ * Trigger then the MFA setup changes.
993
+ */
994
+ this.change = new EventEmitter();
995
+ }
996
+ async ngOnInit() {
997
+ this.isMFAEnabled = await this.auth.checkIfUserHasMFAEnabled(true);
998
+ }
999
+ async openMFAModal() {
1000
+ const modal = await this.modalCtrl.create({ component: IDEASetupMFAModalComponent, backdropDismiss: false });
1001
+ modal.onDidDismiss().then(({ data }) => {
1002
+ if (data) {
1003
+ this.isMFAEnabled = data.enabled;
1004
+ this.change.emit(data.enabled);
1005
+ }
1006
+ });
1007
+ await modal.present();
1008
+ }
1009
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAButtonComponent, deps: [{ token: i1.ModalController }, { token: IDEAAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
1010
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEASetupMFAButtonComponent, selector: "idea-setup-mfa-button", inputs: { color: "color", fill: "fill" }, outputs: { change: "change" }, ngImport: i0, template: "<ion-button *ngIf=\"isMFAEnabled !== undefined\" [color]=\"color\" [fill]=\"fill\" (click)=\"openMFAModal()\">\n {{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA' : 'IDEA_AUTH.SETUP_MFA') | translate }}\n</ion-button>\n", styles: [""], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
1011
+ }
1012
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAButtonComponent, decorators: [{
1013
+ type: Component,
1014
+ args: [{ selector: 'idea-setup-mfa-button', template: "<ion-button *ngIf=\"isMFAEnabled !== undefined\" [color]=\"color\" [fill]=\"fill\" (click)=\"openMFAModal()\">\n {{ (isMFAEnabled ? 'IDEA_AUTH.DISABLE_MFA' : 'IDEA_AUTH.SETUP_MFA') | translate }}\n</ion-button>\n" }]
1015
+ }], ctorParameters: function () { return [{ type: i1.ModalController }, { type: IDEAAuthService }]; }, propDecorators: { color: [{
1016
+ type: Input
1017
+ }], fill: [{
1018
+ type: Input
1019
+ }], change: [{
1020
+ type: Output
1021
+ }] } });
1022
+
1023
+ class IDEASetupMFAPage {
1024
+ constructor(navCtrl) {
1025
+ this.navCtrl = navCtrl;
1026
+ }
1027
+ reloadApp() {
1028
+ window.location.assign('');
1029
+ }
1030
+ goToAuth() {
1031
+ this.navCtrl.navigateBack(['auth']);
1032
+ }
1033
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAPage, deps: [{ token: i1.NavController }], target: i0.ɵɵFactoryTarget.Component }); }
1034
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: IDEASetupMFAPage, selector: "idea-mfa-setup", ngImport: i0, template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.SETUP_MFA' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.MFA_IS_MANDATORY' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <idea-setup-mfa-button (change)=\"reloadApp()\"></idea-setup-mfa-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"], dependencies: [{ kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IDEASetupMFAButtonComponent, selector: "idea-setup-mfa-button", inputs: ["color", "fill"], outputs: ["change"] }, { kind: "pipe", type: i2.IDEATranslatePipe, name: "translate" }] }); }
1035
+ }
1036
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAPage, decorators: [{
1037
+ type: Component,
1038
+ args: [{ selector: 'idea-mfa-setup', template: "<ion-content>\n <form class=\"flexBox\">\n <ion-card class=\"authCard\">\n <ion-card-header>\n <ion-card-title color=\"primary\">{{ 'IDEA_AUTH.SETUP_MFA' | translate }}</ion-card-title>\n <ion-card-subtitle>{{ 'IDEA_AUTH.MFA_IS_MANDATORY' | translate }}</ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <idea-setup-mfa-button (change)=\"reloadApp()\"></idea-setup-mfa-button>\n <ion-button\n fill=\"clear\"\n expand=\"block\"\n class=\"smallCaseButton\"\n [title]=\"'IDEA_AUTH.BACK_TO_SIGN_IN_HINT' | translate\"\n (click)=\"goToAuth()\"\n >\n {{ 'IDEA_AUTH.BACK_TO_SIGN_IN' | translate }}\n </ion-button>\n </ion-card-content>\n </ion-card>\n </form>\n</ion-content>\n", styles: [".flexBox{background:var(--idea-auth-background-color, var(--ion-color-white-shade))}.authCard{min-width:400px;max-width:550px;margin:0 10px;padding:20px;background-color:var(--idea-auth-card-background-color, var(--ion-color-white));border:1px solid var(--idea-auth-card-border-color, var(--ion-color-light));border-radius:10px;box-shadow:none;text-align:center}.authCard ion-img{width:150px;display:block;margin:0 auto}.authCard ion-card-title{font-family:auth-title;font-size:3em}.authCard ion-card-subtitle{font-family:auth-title;font-size:1.2em}.authCard ion-card-content{padding-top:16px}.authCard ion-card-content .errorBox{padding-left:10px;margin-bottom:20px;text-align:left;border-left:2px solid var(--ion-color-danger)}.authCard ion-card-content ion-item{--ion-item-background: var(--idea-auth-card-background-color, var(--ion-color-white));--border-color: var(--idea-auth-card-border-color, var(--ion-color-light))}.authCard ion-card-content ion-label[position=inline] ion-icon{padding-top:4px;padding-right:5px;font-size:1.3em}.authCard ion-card-content .agreementsAcceptanceRow{margin-top:15px;font-size:.9em}.authCard ion-card-content .agreementsAcceptanceRow ion-checkbox{vertical-align:bottom;margin-right:3px}.authCard ion-card-content ion-button:not([slot=end]){margin-top:15px}.authCard ion-card-content .smallCaseButton{text-transform:none;letter-spacing:normal;font-size:1em}@media only screen and (max-width: 500px){.authCard{background-color:transparent;border:none}}.ideaLogo{width:65px;margin:40px auto 0;cursor:pointer}.passwordPolicyPopover{--width: 350px}\n"] }]
1039
+ }], ctorParameters: function () { return [{ type: i1.NavController }]; } });
1040
+
1041
+ class IDEASetupMFAModule {
1042
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1043
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAModule, declarations: [IDEASetupMFAModalComponent, IDEASetupMFAButtonComponent], imports: [CommonModule, FormsModule, IonicModule, IDEATranslationsModule], exports: [IDEASetupMFAModalComponent, IDEASetupMFAButtonComponent] }); }
1044
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAModule, imports: [CommonModule, FormsModule, IonicModule, IDEATranslationsModule] }); }
1045
+ }
1046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEASetupMFAModule, decorators: [{
1047
+ type: NgModule,
1048
+ args: [{
1049
+ imports: [CommonModule, FormsModule, IonicModule, IDEATranslationsModule],
1050
+ declarations: [IDEASetupMFAModalComponent, IDEASetupMFAButtonComponent],
1051
+ exports: [IDEASetupMFAModalComponent, IDEASetupMFAButtonComponent]
1052
+ }]
1053
+ }] });
1054
+
1055
+ class IDEAAuthModule {
1056
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1057
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthModule, declarations: [IDEASignInPage,
1058
+ IDEASignUpPage,
1059
+ IDEANewPasswordPage,
1060
+ IDEAResendLinkPage,
1061
+ IDEAForgotPasswordPage,
1062
+ IDEAConfirmPasswordPage,
1063
+ IDEAMFAChallengePage,
1064
+ IDEASetupMFAPage,
1065
+ IDEAPasswordPolicyComponent], imports: [CommonModule,
1066
+ FormsModule,
1067
+ IonicModule,
1068
+ IDEATranslationsModule, i2$1.RouterModule, IDEASetupMFAModule] }); }
1069
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthModule, imports: [CommonModule,
1070
+ FormsModule,
1071
+ IonicModule,
1072
+ IDEATranslationsModule,
1073
+ RouterModule.forChild([
1074
+ { path: '', redirectTo: 'sign-in', pathMatch: 'full' },
1075
+ { path: 'sign-in', component: IDEASignInPage },
1076
+ { path: 'sign-up', component: IDEASignUpPage },
1077
+ { path: 'new-password', component: IDEANewPasswordPage },
1078
+ { path: 'mfa-challenge', component: IDEAMFAChallengePage },
1079
+ { path: 'setup-mfa', component: IDEASetupMFAPage },
1080
+ { path: 'resend-link', component: IDEAResendLinkPage },
1081
+ { path: 'forgot-password', component: IDEAForgotPasswordPage },
1082
+ { path: 'confirm-password', component: IDEAConfirmPasswordPage }
1083
+ ]),
1084
+ IDEASetupMFAModule] }); }
1085
+ }
1086
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: IDEAAuthModule, decorators: [{
1087
+ type: NgModule,
1088
+ args: [{
1089
+ imports: [
1090
+ CommonModule,
1091
+ FormsModule,
1092
+ IonicModule,
1093
+ IDEATranslationsModule,
1094
+ RouterModule.forChild([
1095
+ { path: '', redirectTo: 'sign-in', pathMatch: 'full' },
1096
+ { path: 'sign-in', component: IDEASignInPage },
1097
+ { path: 'sign-up', component: IDEASignUpPage },
1098
+ { path: 'new-password', component: IDEANewPasswordPage },
1099
+ { path: 'mfa-challenge', component: IDEAMFAChallengePage },
1100
+ { path: 'setup-mfa', component: IDEASetupMFAPage },
1101
+ { path: 'resend-link', component: IDEAResendLinkPage },
1102
+ { path: 'forgot-password', component: IDEAForgotPasswordPage },
1103
+ { path: 'confirm-password', component: IDEAConfirmPasswordPage }
1104
+ ]),
1105
+ IDEASetupMFAModule
1106
+ ],
1107
+ declarations: [
1108
+ IDEASignInPage,
1109
+ IDEASignUpPage,
1110
+ IDEANewPasswordPage,
1111
+ IDEAResendLinkPage,
1112
+ IDEAForgotPasswordPage,
1113
+ IDEAConfirmPasswordPage,
1114
+ IDEAMFAChallengePage,
1115
+ IDEASetupMFAPage,
1116
+ IDEAPasswordPolicyComponent
1117
+ ]
1118
+ }]
1119
+ }] });
1120
+
1121
+ /**
1122
+ * Generated bundle index. Do not edit.
1123
+ */
1124
+
1125
+ export { IDEAAuthModule, IDEAAuthService, IDEASetupMFAButtonComponent, IDEASetupMFAModalComponent, IDEASetupMFAModule, LoginOutcomeActions };
1126
+ //# sourceMappingURL=idea-ionic-auth.mjs.map