PageSourceSearch

https://manage.sslforfree.com/js/scripts.preapp.js

js sslforfree.com collected 2026-10-03 21:45:44 UTC 14,082 bytes, 523 lines download raw bytes

1(function () {
2	"use strict";
3
4	if (typeof window.jQuery === "undefined") {
5		const message = "scripts.preapp.js: jQuery is required but not loaded before this script.";
6
7		console.error(message);
8
9		if (window.Sentry && typeof window.Sentry.captureMessage === "function") {
10			window.Sentry.captureMessage(message, { level: "error" });
11		}
12
13		return;
14	}
15
16	const $ = window.jQuery;
17
18	/* LOGIN */
19	$('body').on('submit', 'form[name="login"]', async function(e) {
20		"use strict";
21		e.preventDefault();
22
23		var button = $(this).find('button[type="submit"]');
24
25		var emailInput = $('body').find('[name="login[email]"]');
26		var passwordInput = $('body').find('[name="login[password]"]');
27		var passwordValue = passwordInput.val();
28
29		var error = false;
30
31		if (!emailInput.val() || !isValidEmailAddress(emailInput.val())) {
32		error = true;
33		emailInput.addClass('error');
34		} else {
35		emailInput.removeClass('error');
36		}
37
38		if (!passwordInput.val()) {
39		error = true;
40		passwordInput.addClass('error');
41		} else {
42		passwordInput.removeClass('error');
43		}
44
45		if (error === true) {
46		generalInfo('show', 'error', 'There were errors. Please try again.');
47		return false;
48		} else {
49		generalInfo('hide');
50		}
51
52		button.addClass('loading');
53
54		var	postData = {
55			email_address: emailInput.val(),
56			password: await generateSHA256(passwordInput.val()),
57		};
58
59		var postDataJSON = JSON.stringify(postData);
60		//console.log(postDataJSON);
61
62		$.ajax({
63			type: "POST",
64			url: '/ajax/public_ajax_handler.php?type=sign_in',
65			data: ({ postArray: postDataJSON }),
66			dataType: "json",
67			error: function(XMLHttpRequest, textStatus, errorThrown) {
68				//alert(textStatus + ', ' + errorThrown);
69			},
70			success: async function(data){
71				if (data.success === 1) {
72					// store encryption key
73					await storeEncryptionKey(passwordValue);
74
75					const params = new URLSearchParams(window.location.search);
76					const redirectParam = params.get('u');
77					let redirectUrl = '/dashboard';
78
79					if (redirectParam) {
80						try {
81							const decodedUrl = decodeURIComponent(redirectParam);
82							const targetUrl = new URL(decodedUrl, window.location.origin);
83
84							if (targetUrl.origin === window.location.origin) {
85								redirectUrl = targetUrl.pathname + targetUrl.search + targetUrl.hash;
86							}
87						} catch (e) {
88							// ignore malformed URLs
89						}
90					}
91
92					const winbackPlanId = parseInt(getCookie('winback_plan'), 10);
93					if (winbackPlanId && !isNaN(winbackPlanId)) {
94						eraseCookie('winback_plan');
95						const winbackPostData = JSON.stringify({
96							plan_id: winbackPlanId,
97							payment_frequency: 'yearly',
98							source: 'winback',
99						});
100						$.ajax({
101							type: 'POST',
102							url: '/ajax/advanced_ajax_handler.php?type=change_subscription_plan&_cpt=' + getCookie('_cpt'),
103							data: { postArray: winbackPostData },
104							dataType: 'json',
105							success: function (winbackData) {
106								if (winbackData.success === 1 && winbackData.message && winbackData.message.payment_required === 1 && winbackData.message.invoice_id) {
107									window.location.href = '/checkout/' + winbackData.message.invoice_id;
108								} else if (winbackData.message === 'winback_free_plan_required') {
109									window.location.href = '/dashboard?winback=not_free';
110								} else {
111									window.location.href = '/dashboard?winback=failed';
112								}
113							},
114							error: function () {
115								window.location.href = '/dashboard?winback=failed';
116							}
117						});
118						return false;
119					}
120
121					window.location.href = redirectUrl;
122					return false;
123				}  else {
124					button.removeClass('loading');
125
126					if ($('body').attr('data-sslforfree') === 'true') {
127						generalInfo('show', 'error', (data.message ? data.message : 'Login failed: Incorrect email or password') + '<br><br>Please note that log-ins from before May 18th no longer work. To keep using our product, please <a title="Sign Up" href="/signup">create a new account for free.</a>');
128					} else {
129						generalInfo('show', 'error', data.message ? data.message : 'Login failed: Incorrect email or password');
130					}
131					return false;
132				}
133
134			}
135
136		});
137
138	});
139
140	/* FORGOT PASSWORD */
141	$('body').on('submit', 'form[name="forgot"]', function(e) {
142		"use strict";
143		e.preventDefault();
144
145		var button = $(this).find('button[type="submit"]');
146
147		var emailInput = $('body').find('[name="forgot[email]"]');
148
149		var error = false;
150
151		if (!emailInput.val() || !isValidEmailAddress(emailInput.val())) {
152		error = true;
153		emailInput.addClass('error');
154		} else {
155		emailInput.removeClass('error');
156		}
157
158		if (error === true) {
159		generalInfo('show', 'error', 'Invalid account email. Please try again.');
160		return false;
161		} else {
162		generalInfo('hide');
163		}
164
165		button.addClass('loading');
166
167		var	postData = {
168			email_address: emailInput.val(),
169		};
170
171		var postDataJSON = JSON.stringify(postData);
172		//console.log(postDataJSON);
173
174		$.ajax({
175			type: "POST",
176			url: '/ajax/public_ajax_handler.php?type=reset_password',
177			data: ({ postArray: postDataJSON }),
178			dataType: "json",
179			error: function(XMLHttpRequest, textStatus, errorThrown) {
180				//alert(textStatus + ', ' + errorThrown);
181			},
182			success: function(data){
183
184				if (data.success === 1) {
185
186					button.removeClass('loading');
187
188					generalInfo('show', 'success', 'An email with account recovery instructions has been sent to your email address.');
189					return false;
190
191				}  else {
192
193					button.removeClass('loading');
194
195					generalInfo('show', 'error', 'An error occurred. Please try again.');
196					return false;
197
198				}
199
200			}
201
202		});
203
204
205	});
206
207
208	/* FINALIZE RESET PASSWORD */
209	$('body').on('submit', 'form[name="reset"]', async function(e) {
210		"use strict";
211		e.preventDefault();
212
213		var button = $(this).find('button[type="submit"]');
214
215		var newPasswordInput = $('body').find('[name="reset[new_password]"]');
216		var newPasswordAgainInput = $('body').find('[name="reset[new_password_again]"]');
217
218		/* product-based password error messages */
219		var passwordErrorMessage = 'New password must contain: 8 characters or more, including lowercase, uppercase characters and a number.';
220
221		if (isProduct === 'sslforfree') {
222		passwordErrorMessage = 'Password must contain at least 6 characters';
223		}
224
225		// check password strength, custom error
226		if (!newPasswordInput.val() || !passwordStrength(newPasswordInput.val())) {
227		generalInfo('show', 'error', passwordErrorMessage);
228		return false;
229		} else {
230		generalInfo('hide');
231		newPasswordInput.removeClass('error');
232		}
233
234		if (!newPasswordAgainInput.val() || newPasswordInput.val() !== newPasswordAgainInput.val()) {
235		newPasswordAgainInput.addClass('error');
236		generalInfo('show', 'error', 'Your new passwords must match.');
237		return false;
238		} else {
239		generalInfo('hide');
240		newPasswordAgainInput.removeClass('error');
241		}
242
243		button.addClass('loading');
244
245		var	postData = {
246			new_password: await generateSHA256(newPasswordInput.val()),
247			new_password_again: await generateSHA256(newPasswordAgainInput.val()),
248			key: $('body').find('[name="key"]').val()
249		};
250
251		var postDataJSON = JSON.stringify(postData);
252		//console.log(postDataJSON);
253
254		$.ajax({
255			type: "POST",
256			url: '/ajax/public_ajax_handler.php?type=finalize_reset_password',
257			data: ({ postArray: postDataJSON }),
258			dataType: "json",
259			error: function(XMLHttpRequest, textStatus, errorThrown) {
260				//alert(textStatus + ', ' + errorThrown);
261			},
262			success: function(data){
263
264				if (data.success === 1) {
265
266					// set cookie in client that invalidates all private keys on next login
267					localStorage.setItem('inv_pk', 'true');
268
269					window.location.href = '/login/recovered';
270					return false;
271
272				}  else {
273
274					button.removeClass('loading');
275
276					generalInfo('show', 'error', 'Error: Please try again or contact support.');
277					return false;
278
279				}
280
281			}
282
283		});
284
285
286	});
287
288
289	/* SIGNUP */
290	$('body').on('submit', 'form[name="signup"]', async function(e) {
291		"use strict";
292		e.preventDefault();
293
294		generateRecaptchaToken();
295
296		var button = $(this).find('button[type="submit"]');
297
298		var emailInput = $('body').find('[name="signup[email]"]');
299		var passwordInput = $('body').find('[name="signup[password]"]');
300		var countryInput = $('body').find('[name="signup[country_code]"]');
301
302		var passwordValue = passwordInput.val();
303
304		var error = false;
305
306		if (!emailInput.val() || !isValidEmailAddress(emailInput.val())) {
307			error = true;
308			emailInput.addClass('error');
309		} else {
310			emailInput.removeClass('error');
311		}
312
313		if (!passwordInput.val()) {
314			error = true;
315			passwordInput.addClass('error');
316		} else {
317			passwordInput.removeClass('error');
318		}
319
320		if (!countryInput.val()) {
321			error = true;
322			countryInput.addClass('error');
323		} else {
324			countryInput.removeClass('error');
325		}
326
327		if (error === true) {
328			generalInfo('show', 'error', 'There were errors. Please try again.');
329		return false;
330		} else {
331			generalInfo('hide');
332		}
333
334		/* product-based password error messages */
335		var passwordErrorMessage = 'Your password must contain 8 characters or more, including lowercase, uppercase characters and a number.';
336
337		if (isProduct === 'sslforfree') {
338		passwordErrorMessage = 'Password must contain at least 6 characters';
339		}
340
341		if (!passwordStrength(passwordInput.val())) {
342
343			passwordInput.addClass('error');
344			generalInfo('show', 'error', passwordErrorMessage);
345
346			return false;
347
348		} else {
349			generalInfo('hide');
350			passwordInput.removeClass('error');
351		}
352
353		button.addClass('loading');
354
355		var domainToSecure = $('body').find('[name="signup[domain]"]').val();
356
357		let v2Response = null;
358		try {
359			v2Response = grecaptcha.getResponse();
360		} catch {
361			// usually the case, v2Response is only for the fallback
362		}
363
364		var	postData = {
365			email_address: emailInput.val(),
366			password: await generateSHA256(passwordInput.val()),
367			payment_frequency: 'yearly',
368			country_code: $('body').find('[name="signup[country_code]"]').val(),
369			domain: $('body').find('[name="signup[domain]"]').val(),
370			plan_id: $('body').find('[name="signup[plan_id]"]').val(),
371			token: $('body').find('[name="recaptcha_token"]').val(),
372			v2response: v2Response,
373			origin: $('body').find('[name="signup[origin]"]').val(),
374			origin_full: $('body').find('[name="signup[origin_full]"]').val(),
375		};
376
377		var postDataJSON = JSON.stringify(postData);
378		//console.log(postDataJSON);
379
380		$.ajax({
381			type: "POST",
382			url: '/ajax/public_ajax_handler.php?type=create_account',
383			data: ({ postArray: postDataJSON }),
384			dataType: "json",
385			error: function(XMLHttpRequest, textStatus, errorThrown) {
386				//alert(textStatus + ', ' + errorThrown);
387			},
388			success: async function(data){
389				if (data.success === 1) {
390					// store encryption key
391					await storeEncryptionKey(passwordValue);
392
393					if (data?.message?.payment_required === 1) {
394						window.location.href = '/checkout/'+data.message.invoice_id;
395					} else {
396						setCookie('free_client_onboarding', domainToSecure)
397						window.location.href = '/select-plan';
398					}
399					return false;
400			} else {
401					button.removeClass('loading');
402					if(parseInt(data.success) === -10) {
403						let url = window.location.href;
404						if (url.indexOf('?') > -1){
405							url += '&sverify=1&email=' + emailInput.val()
406						} else {
407							url += '?sverify=1&email=' + emailInput.val()
408						}
409						window.location.href = url;
410					} else {
411						generalInfo('show', 'error', translateError(data.message));
412						return false;
413					}
414				}
415
416			}
417
418		});
419
420	});
421
422
423
424	/* CTA FOOTER SUBMISSION */
425	$('body').on('click', '[data-action="submit_footer_cta"]', function(event) {
426
427		event.preventDefault();
428
429		var email = $('body').find('[name="cta_email"]').val();
430
431		if (!isValidEmailAddress(email)) {
432		email = '';
433		}
434
435		// redirect to signup
436		window.location.href = 'https://app.zerossl.com/signup/email/' + email;
437
438	});
439
440
441	$('body').on('submit', 'form[name="otp"]', function(e) {
442		"use strict";
443		e.preventDefault();
444
445		var button = $(this).find('button[type="submit"]');
446
447		var otpInput = $('body').find('[name="otp[otp]"]');
448
449		var otpError = $('body').find('.otp-error');
450
451		button.addClass('loading');
452		otpError.hide();
453
454		var	postData = {
455			otp: otpInput.val(),
456		};
457
458		var postDataJSON = JSON.stringify(postData);
459
460		$.ajax({
461			type: "POST",
462			url: '/ajax/public_ajax_handler.php?type=verify_otp',
463			data: ({ postArray: postDataJSON }),
464			dataType: "json",
465			success: function(data){
466				if(data.success === 1) {
467					location.reload();
468				} else {
469
470					button.removeClass('loading');
471
472					otpError.html(data.message)
473					otpError.show();
474				}
475			}
476
477		});
478
479	});
480})();
481
482function handleSubscriptionChangeSuccess(responseObject) {
483	setCookie('free_client_onboarding', '', -1);
484	location.href = '/checkout/'+responseObject.invoice_id;
485}
486
487function proceedWithFreeAccount(e) {
488	e.preventDefault();
489	setCookie('free_client_onboarding', '', -1);
490	location.href = e.target.href;
491}
492
493/* WINBACK PRE-LOGIN SURVEY
494 * Runs on /login?winback=1. Opens the winback popup and delegates survey
495 * initialisation to window.WinbackSurvey. On a valid plan selection the plan
496 * ID is saved to the winback_plan cookie; after login the user is redirected
497 * to checkout.
498 */
499$(document).ready(function () {
500	if (!$('#login[data-winback]').length) {
501		return;
502	}
503
504	openPopup('confirm_winback_survey_prelogin', undefined, function () {
505		var surveyElem = $('#winbackSurvey');
506		var confirmButton = $('#confirmWinBackButton');
507
508		window.WinbackSurvey.init(surveyElem, confirmButton, {
509			origin: surveyElem.data('origin'),
510			env: surveyElem.data('env') || ''
511		}, function (planId) {
512			if (planId) {
513				setCookie('winback_plan', planId, 1);
514				confirmButton.addClass('primary');
515
516				const planNames = { 1128: 'Basic', 1129: 'Premium', 1130: 'Business' };
517				const planName = planNames[planId] || 'selected';
518				$('.alerts').find('.winback-plan-alert').remove();
519				$('.alerts').append('<p class="alert success winback-plan-alert">You\'ve selected the <strong>' + planName + '</strong> plan. Log in below and you\'ll be redirected to checkout automatically.</p>');
520			}
521		});
522	}, undefined, 'full-screen');
523});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.