Commit 13ac08a4 by Uman Shahzad

Allow configurable password reset support link.

Defaults to SUPPORT_SITE_LINK intentionally.
Also fixed surrounding quality tests, and overall
quality improvements.
parent 0e49da8d
......@@ -94,6 +94,7 @@ from lms.envs.common import (
HELP_TOKENS_BOOKS,
SUPPORT_SITE_LINK,
PASSWORD_RESET_SUPPORT_LINK,
ACTIVATION_EMAIL_SUPPORT_LINK,
CONTACT_EMAIL,
......
......@@ -133,6 +133,9 @@ def login_and_registration_form(request, initial_mode="login"):
'third_party_auth_hint': third_party_auth_hint or '',
'platform_name': configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
'support_link': configuration_helpers.get_value('SUPPORT_SITE_LINK', settings.SUPPORT_SITE_LINK),
'password_reset_support_link': configuration_helpers.get_value(
'PASSWORD_RESET_SUPPORT_LINK', settings.PASSWORD_RESET_SUPPORT_LINK
) or settings.SUPPORT_SITE_LINK,
'account_activation_messages': account_activation_messages,
# Include form descriptions retrieved from the user API.
......@@ -560,6 +563,9 @@ def account_settings_context(request):
}
},
'platform_name': configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
'password_reset_support_link': configuration_helpers.get_value(
'PASSWORD_RESET_SUPPORT_LINK', settings.PASSWORD_RESET_SUPPORT_LINK
) or settings.SUPPORT_SITE_LINK,
'user_accounts_api_url': reverse("accounts_api", kwargs={'username': user.username}),
'user_preferences_api_url': reverse('preferences_api', kwargs={'username': user.username}),
'disable_courseware_js': True,
......
......@@ -309,9 +309,11 @@ ENABLE_COMPREHENSIVE_THEMING = ENV_TOKENS.get('ENABLE_COMPREHENSIVE_THEMING', EN
# Marketing link overrides
MKTG_URL_LINK_MAP.update(ENV_TOKENS.get('MKTG_URL_LINK_MAP', {}))
# Intentional defaults.
SUPPORT_SITE_LINK = ENV_TOKENS.get('SUPPORT_SITE_LINK', SUPPORT_SITE_LINK)
PASSWORD_RESET_SUPPORT_LINK = ENV_TOKENS.get('PASSWORD_RESET_SUPPORT_LINK', SUPPORT_SITE_LINK)
ACTIVATION_EMAIL_SUPPORT_LINK = ENV_TOKENS.get(
'ACTIVATION_EMAIL_SUPPORT_LINK', SUPPORT_SITE_LINK # Intentional default.
'ACTIVATION_EMAIL_SUPPORT_LINK', SUPPORT_SITE_LINK
)
# Mobile store URL overrides
......
......@@ -137,6 +137,7 @@
"SITE_NAME": "localhost:8003",
"STATIC_URL_BASE": "/static/",
"SUPPORT_SITE_LINK": "https://support.example.com",
"PASSWORD_RESET_SUPPORT_LINK": "https://support.example.com/password-reset-help.html",
"ACTIVATION_EMAIL_SUPPORT_LINK": "https://support.example.com/activation-email-help.html",
"SYSLOG_SERVER": "",
"TECH_SUPPORT_EMAIL": "technical@example.com",
......
......@@ -2271,6 +2271,7 @@ MKTG_URL_LINK_MAP = {
STATIC_TEMPLATE_VIEW_DEFAULT_FILE_EXTENSION = 'html'
SUPPORT_SITE_LINK = ''
PASSWORD_RESET_SUPPORT_LINK = ''
ACTIVATION_EMAIL_SUPPORT_LINK = ''
############################# SOCIAL MEDIA SHARING #############################
......
......@@ -361,6 +361,7 @@ MKTG_URL_LINK_MAP = {
}
SUPPORT_SITE_LINK = 'https://support.example.com'
PASSWORD_RESET_SUPPORT_LINK = 'https://support.example.com/password-reset-help.html'
ACTIVATION_EMAIL_SUPPORT_LINK = 'https://support.example.com/activation-email-help.html'
############################ STATIC FILES #############################
......
......@@ -14,50 +14,15 @@ define(['backbone',
'use strict';
describe('edx.user.AccountSettingsFactory', function() {
var FIELDS_DATA = {
'country': {
'options': Helpers.FIELD_OPTIONS
}, 'gender': {
'options': Helpers.FIELD_OPTIONS
}, 'language': {
'options': Helpers.FIELD_OPTIONS
}, 'level_of_education': {
'options': Helpers.FIELD_OPTIONS
}, 'password': {
'url': '/password_reset'
}, 'year_of_birth': {
'options': Helpers.FIELD_OPTIONS
}, 'preferred_language': {
'options': Helpers.FIELD_OPTIONS
}, 'time_zone': {
'options': Helpers.FIELD_OPTIONS
}
};
var AUTH_DATA = {
'providers': [
{
'id': 'oa2-network1',
'name': 'Network1',
'connected': true,
'accepts_logins': 'true',
'connect_url': 'yetanother1.com/auth/connect',
'disconnect_url': 'yetanother1.com/auth/disconnect'
},
{
'id': 'oa2-network2',
'name': 'Network2',
'connected': true,
'accepts_logins': 'true',
'connect_url': 'yetanother2.com/auth/connect',
'disconnect_url': 'yetanother2.com/auth/disconnect'
}
]
};
var createAccountSettingsPage = function() {
var context = AccountSettingsPage(
FIELDS_DATA, [], AUTH_DATA, Helpers.USER_ACCOUNTS_API_URL, Helpers.USER_PREFERENCES_API_URL, 'edX'
Helpers.FIELDS_DATA,
[],
Helpers.AUTH_DATA,
Helpers.PASSWORD_RESET_SUPPORT_LINK,
Helpers.USER_ACCOUNTS_API_URL,
Helpers.USER_PREFERENCES_API_URL,
Helpers.PLATFORM_NAME
);
return context.accountSettingsView;
};
......
......@@ -7,12 +7,63 @@ define(['underscore'], function(_) {
var IMAGE_UPLOAD_API_URL = '/api/profile_images/v0/staff/upload';
var IMAGE_REMOVE_API_URL = '/api/profile_images/v0/staff/remove';
var FIND_COURSES_URL = '/courses';
var PASSWORD_RESET_SUPPORT_LINK = 'https://support.edx.org/hc/en-us/articles/206212088-What-if-I-did-not-receive-a-password-reset-message-'; // eslint-disable-line max-len
var PLATFORM_NAME = 'edX';
var PROFILE_IMAGE = {
image_url_large: '/media/profile-images/image.jpg',
has_image: true
};
var FIELD_OPTIONS = [
['0', 'Option 0'],
['1', 'Option 1'],
['2', 'Option 2'],
['3', 'Option 3']
];
var TIME_ZONE_RESPONSE = [{
time_zone: 'America/Guyana',
description: 'America/Guyana (ECT, UTC-0500)'
}];
var FIELDS_DATA = {
country: {
options: FIELD_OPTIONS
}, gender: {
options: FIELD_OPTIONS
}, language: {
options: FIELD_OPTIONS
}, level_of_education: {
options: FIELD_OPTIONS
}, password: {
url: '/password_reset'
}, year_of_birth: {
options: FIELD_OPTIONS
}, preferred_language: {
options: FIELD_OPTIONS
}, time_zone: {
options: FIELD_OPTIONS
}
};
var AUTH_DATA = {
providers: [
{
id: 'oa2-network1',
name: 'Network1',
connected: true,
accepts_logins: 'true',
connect_url: 'yetanother1.com/auth/connect',
disconnect_url: 'yetanother1.com/auth/disconnect'
},
{
id: 'oa2-network2',
name: 'Network2',
connected: true,
accepts_logins: 'true',
connect_url: 'yetanother2.com/auth/connect',
disconnect_url: 'yetanother2.com/auth/disconnect'
}
]
};
var IMAGE_MAX_BYTES = 1024 * 1024;
var IMAGE_MIN_BYTES = 100;
var DEFAULT_ACCOUNT_SETTINGS_DATA = {
username: 'student',
name: 'Student',
......@@ -28,35 +79,19 @@ define(['underscore'], function(_) {
profile_image: PROFILE_IMAGE,
accomplishments_shared: false
};
var createAccountSettingsData = function(options) {
return _.extend(_.extend({}, DEFAULT_ACCOUNT_SETTINGS_DATA), options);
};
var DEFAULT_USER_PREFERENCES_DATA = {
'pref-lang': '2',
'time_zone': null
};
var createAccountSettingsData = function(options) {
return _.extend(_.extend({}, DEFAULT_ACCOUNT_SETTINGS_DATA), options);
};
var createUserPreferencesData = function(options) {
return _.extend(_.extend({}, DEFAULT_USER_PREFERENCES_DATA), options);
};
var FIELD_OPTIONS = [
['0', 'Option 0'],
['1', 'Option 1'],
['2', 'Option 2'],
['3', 'Option 3']
];
var TIME_ZONE_RESPONSE = [{
time_zone: 'America/Guyana',
description: 'America/Guyana (ECT, UTC-0500)'
}];
var IMAGE_MAX_BYTES = 1024 * 1024;
var IMAGE_MIN_BYTES = 100;
var expectLoadingIndicatorIsVisible = function(view, visible) {
if (visible) {
expect($('.ui-loading-indicator')).not.toHaveClass('is-hidden');
......@@ -88,10 +123,6 @@ define(['underscore'], function(_) {
}
};
var expectSettingsSectionsButNotFieldsToBeRendered = function(accountSettingsView) {
expectSettingsSectionsAndFieldsToBeRendered(accountSettingsView, false);
};
var expectSettingsSectionsAndFieldsToBeRendered = function(accountSettingsView, fieldsAreRendered) {
var sectionsData = accountSettingsView.options.tabSections.aboutTabSections;
......@@ -99,7 +130,8 @@ define(['underscore'], function(_) {
expect(sectionElements.length).toBe(sectionsData.length);
_.each(sectionElements, function(sectionElement, sectionIndex) {
expect($(sectionElement).find('.section-header').text().trim()).toBe(sectionsData[sectionIndex].title);
expect($(sectionElement).find('.section-header').text()
.trim()).toBe(sectionsData[sectionIndex].title);
var sectionFieldElements = $(sectionElement).find('.u-field');
......@@ -115,6 +147,10 @@ define(['underscore'], function(_) {
});
};
var expectSettingsSectionsButNotFieldsToBeRendered = function(accountSettingsView) {
expectSettingsSectionsAndFieldsToBeRendered(accountSettingsView, false);
};
return {
USER_ACCOUNTS_API_URL: USER_ACCOUNTS_API_URL,
USER_PREFERENCES_API_URL: USER_PREFERENCES_API_URL,
......@@ -122,13 +158,17 @@ define(['underscore'], function(_) {
FIND_COURSES_URL: FIND_COURSES_URL,
IMAGE_UPLOAD_API_URL: IMAGE_UPLOAD_API_URL,
IMAGE_REMOVE_API_URL: IMAGE_REMOVE_API_URL,
PASSWORD_RESET_SUPPORT_LINK: PASSWORD_RESET_SUPPORT_LINK,
PLATFORM_NAME: PLATFORM_NAME,
PROFILE_IMAGE: PROFILE_IMAGE,
FIELD_OPTIONS: FIELD_OPTIONS,
TIME_ZONE_RESPONSE: TIME_ZONE_RESPONSE,
FIELDS_DATA: FIELDS_DATA,
AUTH_DATA: AUTH_DATA,
IMAGE_MAX_BYTES: IMAGE_MAX_BYTES,
IMAGE_MIN_BYTES: IMAGE_MIN_BYTES,
PROFILE_IMAGE: PROFILE_IMAGE,
createAccountSettingsData: createAccountSettingsData,
createUserPreferencesData: createUserPreferencesData,
FIELD_OPTIONS: FIELD_OPTIONS,
TIME_ZONE_RESPONSE: TIME_ZONE_RESPONSE,
expectLoadingIndicatorIsVisible: expectLoadingIndicatorIsVisible,
expectLoadingErrorIsVisible: expectLoadingErrorIsVisible,
expectElementContainsField: expectElementContainsField,
......
......@@ -72,6 +72,7 @@
this.platformName = options.platform_name;
this.supportURL = options.support_link;
this.passwordResetSupportUrl = options.password_reset_support_link;
this.createAccountOption = options.account_creation_allowed;
// The login view listens for 'sync' events from the reset model
......@@ -129,6 +130,7 @@
accountActivationMessages: this.accountActivationMessages,
platformName: this.platformName,
supportURL: this.supportURL,
passwordResetSupportUrl: this.passwordResetSupportUrl,
createAccountOption: this.createAccountOption
});
......
......@@ -5,206 +5,226 @@
'underscore',
'gettext',
'edx-ui-toolkit/js/utils/html-utils',
'edx-ui-toolkit/js/utils/string-utils',
'js/student_account/views/FormView',
'text!templates/student_account/form_success.underscore',
'text!templates/student_account/form_status.underscore'
],
function($, _, gettext, HtmlUtils, FormView, formSuccessTpl, formStatusTpl) {
return FormView.extend({
el: '#login-form',
tpl: '#login-tpl',
events: {
'click .js-login': 'submitForm',
'click .forgot-password': 'forgotPassword',
'click .login-provider': 'thirdPartyAuth'
},
formType: 'login',
requiredStr: '',
optionalStr: '',
submitButton: '.js-login',
formSuccessTpl: formSuccessTpl,
formStatusTpl: formStatusTpl,
authWarningJsHook: 'js-auth-warning',
passwordResetSuccessJsHook: 'js-password-reset-success',
defaultFormErrorsTitle: gettext('We couldn\'t sign you in.'),
preRender: function(data) {
this.providers = data.thirdPartyAuth.providers || [];
this.hasSecondaryProviders = (
data.thirdPartyAuth.secondaryProviders && data.thirdPartyAuth.secondaryProviders.length
);
this.currentProvider = data.thirdPartyAuth.currentProvider || '';
this.errorMessage = data.thirdPartyAuth.errorMessage || '';
this.platformName = data.platformName;
this.resetModel = data.resetModel;
this.supportURL = data.supportURL;
this.createAccountOption = data.createAccountOption;
this.accountActivationMessages = data.accountActivationMessages;
this.listenTo(this.model, 'sync', this.saveSuccess);
this.listenTo(this.resetModel, 'sync', this.resetEmail);
},
render: function(html) {
var fields = html || '';
$(this.el).html(_.template(this.tpl)({
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context: {
fields: fields,
currentProvider: this.currentProvider,
providers: this.providers,
hasSecondaryProviders: this.hasSecondaryProviders,
platformName: this.platformName,
createAccountOption: this.createAccountOption
}
}));
this.postRender();
return this;
},
postRender: function() {
var formErrorsTitle;
this.$container = $(this.el);
this.$form = this.$container.find('form');
this.$formFeedback = this.$container.find('.js-form-feedback');
this.$submitButton = this.$container.find(this.submitButton);
if (this.errorMessage) {
formErrorsTitle = _.sprintf(
gettext('An error occurred when signing you in to %s.'),
this.platformName
);
this.renderErrors(formErrorsTitle, [this.errorMessage]);
} else if (this.currentProvider) {
/* If we're already authenticated with a third-party
* provider, try logging in. The easiest way to do this
* is to simply submit the form.
*/
this.model.save();
], function(
$, _, gettext,
HtmlUtils,
StringUtils,
FormView,
formSuccessTpl,
formStatusTpl
) {
return FormView.extend({
el: '#login-form',
tpl: '#login-tpl',
events: {
'click .js-login': 'submitForm',
'click .forgot-password': 'forgotPassword',
'click .login-provider': 'thirdPartyAuth'
},
formType: 'login',
requiredStr: '',
optionalStr: '',
submitButton: '.js-login',
formSuccessTpl: formSuccessTpl,
formStatusTpl: formStatusTpl,
authWarningJsHook: 'js-auth-warning',
passwordResetSuccessJsHook: 'js-password-reset-success',
defaultFormErrorsTitle: gettext('We couldn\'t sign you in.'),
preRender: function(data) {
this.providers = data.thirdPartyAuth.providers || [];
this.hasSecondaryProviders = (
data.thirdPartyAuth.secondaryProviders && data.thirdPartyAuth.secondaryProviders.length
);
this.currentProvider = data.thirdPartyAuth.currentProvider || '';
this.errorMessage = data.thirdPartyAuth.errorMessage || '';
this.platformName = data.platformName;
this.resetModel = data.resetModel;
this.supportURL = data.supportURL;
this.passwordResetSupportUrl = data.passwordResetSupportUrl;
this.createAccountOption = data.createAccountOption;
this.accountActivationMessages = data.accountActivationMessages;
this.listenTo(this.model, 'sync', this.saveSuccess);
this.listenTo(this.resetModel, 'sync', this.resetEmail);
},
render: function(html) {
var fields = html || '';
$(this.el).html(_.template(this.tpl)({
// We pass the context object to the template so that
// we can perform variable interpolation using sprintf
context: {
fields: fields,
currentProvider: this.currentProvider,
providers: this.providers,
hasSecondaryProviders: this.hasSecondaryProviders,
platformName: this.platformName,
createAccountOption: this.createAccountOption
}
}));
// Display account activation success or error messages.
this.renderAccountActivationMessages();
},
renderAccountActivationMessages: function() {
_.each(this.accountActivationMessages, this.renderAccountActivationMessage, this);
},
renderAccountActivationMessage: function(message) {
this.renderFormFeedback(this.formStatusTpl, {
jsHook: message.tags,
message: HtmlUtils.HTML(message.message)
});
},
forgotPassword: function(event) {
event.preventDefault();
this.trigger('password-help');
this.clearPasswordResetSuccess();
},
postFormSubmission: function() {
this.clearPasswordResetSuccess();
},
resetEmail: function() {
var email = $('#password-reset-email').val(),
successTitle = gettext('Check Your Email'),
successMessageHtml = HtmlUtils.interpolateHtml(
gettext('{paragraphStart}You entered {boldStart}{email}{boldEnd}. If this email address is associated with your {platform_name} account, we will send a message with password reset instructions to this email address.{paragraphEnd}' + // eslint-disable-line max-len
'{paragraphStart}If you do not receive a password reset message, verify that you entered the correct email address, or check your spam folder.{paragraphEnd}' + // eslint-disable-line max-len
'{paragraphStart}If you need further assistance, {anchorStart}contact technical support{anchorEnd}.{paragraphEnd}'), { // eslint-disable-line max-len
boldStart: HtmlUtils.HTML('<b>'),
boldEnd: HtmlUtils.HTML('</b>'),
paragraphStart: HtmlUtils.HTML('<p>'),
paragraphEnd: HtmlUtils.HTML('</p>'),
email: email,
platform_name: this.platformName,
anchorStart: HtmlUtils.HTML('<a href="' + this.supportURL + '">'),
anchorEnd: HtmlUtils.HTML('</a>')
}
);
this.postRender();
this.clearFormErrors();
this.clearPasswordResetSuccess();
return this;
},
this.renderFormFeedback(this.formSuccessTpl, {
jsHook: this.passwordResetSuccessJsHook,
title: successTitle,
messageHtml: successMessageHtml
});
},
postRender: function() {
var formErrorsTitle;
this.$container = $(this.el);
this.$form = this.$container.find('form');
this.$formFeedback = this.$container.find('.js-form-feedback');
this.$submitButton = this.$container.find(this.submitButton);
thirdPartyAuth: function(event) {
var providerUrl = $(event.currentTarget).data('provider-url') || '';
if (this.errorMessage) {
formErrorsTitle = _.sprintf(
gettext('An error occurred when signing you in to %s.'),
this.platformName
);
this.renderErrors(formErrorsTitle, [this.errorMessage]);
} else if (this.currentProvider) {
/* If we're already authenticated with a third-party
* provider, try logging in. The easiest way to do this
* is to simply submit the form.
*/
this.model.save();
}
if (providerUrl) {
window.location.href = providerUrl;
}
},
saveSuccess: function() {
this.trigger('auth-complete');
this.clearPasswordResetSuccess();
},
saveError: function(error) {
var msg = error.responseText;
if (error.status === 0) {
msg = gettext('An error has occurred. Check your Internet connection and try again.');
} else if (error.status === 500) {
msg = gettext('An error has occurred. Try refreshing the page, or check your Internet connection.');
}
this.errors = ['<li>' + msg + '</li>'];
this.clearPasswordResetSuccess();
/* If we've gotten a 403 error, it means that we've successfully
* authenticated with a third-party provider, but we haven't
* linked the account to an EdX account. In this case,
* we need to prompt the user to enter a little more information
* to complete the registration process.
*/
if (error.status === 403 &&
error.responseText === 'third-party-auth' &&
this.currentProvider) {
this.clearFormErrors();
this.renderAuthWarning();
} else {
this.renderErrors(this.defaultFormErrorsTitle, this.errors);
}
this.toggleDisableButton(false);
},
renderAuthWarning: function() {
var message = _.sprintf(
gettext('You have successfully signed into %(currentProvider)s, but your %(currentProvider)s' +
' account does not have a linked %(platformName)s account. To link your accounts,' +
' sign in now using your %(platformName)s password.'),
{currentProvider: this.currentProvider, platformName: this.platformName}
// Display account activation success or error messages.
this.renderAccountActivationMessages();
},
renderAccountActivationMessages: function() {
_.each(this.accountActivationMessages, this.renderAccountActivationMessage, this);
},
renderAccountActivationMessage: function(message) {
this.renderFormFeedback(this.formStatusTpl, {
jsHook: message.tags,
message: HtmlUtils.HTML(message.message)
});
},
forgotPassword: function(event) {
event.preventDefault();
this.trigger('password-help');
this.clearPasswordResetSuccess();
},
postFormSubmission: function() {
this.clearPasswordResetSuccess();
},
resetEmail: function() {
var email = $('#password-reset-email').val(),
successTitle = gettext('Check Your Email'),
successMessageHtml = HtmlUtils.interpolateHtml(
gettext('{paragraphStart}You entered {boldStart}{email}{boldEnd}. If this email address is associated with your {platform_name} account, we will send a message with password reset instructions to this email address.{paragraphEnd}' + // eslint-disable-line max-len
'{paragraphStart}If you do not receive a password reset message, verify that you entered the correct email address, or check your spam folder.{paragraphEnd}' + // eslint-disable-line max-len
'{paragraphStart}If you need further assistance, {anchorStart}contact technical support{anchorEnd}.{paragraphEnd}'), { // eslint-disable-line max-len
boldStart: HtmlUtils.HTML('<b>'),
boldEnd: HtmlUtils.HTML('</b>'),
paragraphStart: HtmlUtils.HTML('<p>'),
paragraphEnd: HtmlUtils.HTML('</p>'),
email: email,
platform_name: this.platformName,
anchorStart: HtmlUtils.HTML(
StringUtils.interpolate(
'<a href="{passwordResetSupportUrl}">', {
passwordResetSupportUrl: this.passwordResetSupportUrl
}
)
),
anchorEnd: HtmlUtils.HTML('</a>')
}
);
this.clearAuthWarning();
this.renderFormFeedback(this.formStatusTpl, {
jsHook: this.authWarningJsHook,
message: message
});
},
clearPasswordResetSuccess: function() {
var query = '.' + this.passwordResetSuccessJsHook;
this.clearFormFeedbackItems(query);
},
clearAuthWarning: function() {
var query = '.' + this.authWarningJsHook;
this.clearFormFeedbackItems(query);
this.clearFormErrors();
this.clearPasswordResetSuccess();
this.renderFormFeedback(this.formSuccessTpl, {
jsHook: this.passwordResetSuccessJsHook,
title: successTitle,
messageHtml: successMessageHtml
});
},
thirdPartyAuth: function(event) {
var providerUrl = $(event.currentTarget).data('provider-url') || '';
if (providerUrl) {
window.location.href = providerUrl;
}
},
saveSuccess: function() {
this.trigger('auth-complete');
this.clearPasswordResetSuccess();
},
saveError: function(error) {
var msg = error.responseText;
if (error.status === 0) {
msg = gettext('An error has occurred. Check your Internet connection and try again.');
} else if (error.status === 500) {
msg = gettext('An error has occurred. Try refreshing the page, or check your Internet connection.'); // eslint-disable-line max-len
}
this.errors = [
StringUtils.interpolate(
'<li>{msg}</li>', {
msg: msg
}
)
];
this.clearPasswordResetSuccess();
/* If we've gotten a 403 error, it means that we've successfully
* authenticated with a third-party provider, but we haven't
* linked the account to an EdX account. In this case,
* we need to prompt the user to enter a little more information
* to complete the registration process.
*/
if (error.status === 403 &&
error.responseText === 'third-party-auth' &&
this.currentProvider) {
this.clearFormErrors();
this.renderAuthWarning();
} else {
this.renderErrors(this.defaultFormErrorsTitle, this.errors);
}
});
this.toggleDisableButton(false);
},
renderAuthWarning: function() {
var message = _.sprintf(
gettext('You have successfully signed into %(currentProvider)s, but your %(currentProvider)s' +
' account does not have a linked %(platformName)s account. To link your accounts,' +
' sign in now using your %(platformName)s password.'),
{currentProvider: this.currentProvider, platformName: this.platformName}
);
this.clearAuthWarning();
this.renderFormFeedback(this.formStatusTpl, {
jsHook: this.authWarningJsHook,
message: message
});
},
clearPasswordResetSuccess: function() {
var query = '.' + this.passwordResetSuccessJsHook;
this.clearFormFeedbackItems(query);
},
clearAuthWarning: function() {
var query = '.' + this.authWarningJsHook;
this.clearFormFeedbackItems(query);
}
});
});
}).call(this, define || RequireJS.define);
......@@ -13,6 +13,7 @@
fieldsData,
ordersHistoryData,
authData,
passwordResetSupportUrl,
userAccountsApiUrl,
userPreferencesApiUrl,
accountUserId,
......@@ -76,6 +77,7 @@
screenReaderTitle: gettext('Reset Your Password'),
valueAttribute: 'password',
emailAttribute: 'email',
passwordResetSupportUrl: passwordResetSupportUrl,
linkTitle: gettext('Reset Your Password'),
linkHref: fieldsData.password.url,
helpMessage: StringUtils.interpolate(
......@@ -191,7 +193,7 @@
),
fields: _.map(authData.providers, function(provider) {
return {
'view': new AccountSettingsFieldViews.AuthFieldView({
view: new AccountSettingsFieldViews.AuthFieldView({
title: provider.name,
valueAttribute: 'auth-' + provider.id,
helpMessage: '',
......@@ -208,10 +210,10 @@
ordersHistoryData.unshift(
{
'title': gettext('ORDER NAME'),
'order_date': gettext('ORDER PLACED'),
'price': gettext('TOTAL'),
'number': gettext('ORDER NUMBER')
title: gettext('ORDER NAME'),
order_date: gettext('ORDER PLACED'),
price: gettext('TOTAL'),
number: gettext('ORDER NUMBER')
}
);
......@@ -228,7 +230,7 @@
orderNumber = 'orderId';
}
return {
'view': new AccountSettingsFieldViews.OrderHistoryFieldView({
view: new AccountSettingsFieldViews.OrderHistoryFieldView({
totalPrice: order.price,
orderId: order.number,
orderDate: order.order_date,
......
......@@ -25,8 +25,7 @@
field_order_history_template,
StringUtils,
HtmlUtils
)
{
) {
var AccountSettingsFieldViews = {
ReadonlyFieldView: FieldViews.ReadonlyFieldView.extend({
fieldTemplate: field_readonly_account_template
......@@ -44,7 +43,7 @@
this.indicators.success,
StringUtils.interpolate(
gettext('We\'ve sent a confirmation message to {new_email_address}. Click the link in the message to update your email address.'), // eslint-disable-line max-len
{'new_email_address': this.fieldValue()}
{new_email_address: this.fieldValue()}
)
);
}
......@@ -53,7 +52,7 @@
fieldTemplate: field_dropdown_account_template,
saveSucceeded: function() {
var data = {
'language': this.modelValue()
language: this.modelValue()
};
var view = this;
......@@ -189,9 +188,19 @@
successMessage: function() {
return HtmlUtils.joinHtml(
this.indicators.success,
StringUtils.interpolate(
gettext('We\'ve sent a message to {email_address}. Click the link in the message to reset your password.'), // eslint-disable-line max-len
{'email_address': this.model.get(this.options.emailAttribute)}
HtmlUtils.interpolateHtml(
gettext('We\'ve sent a message to {email}. Click the link in the message to reset your password. Didn\'t receive the message? Contact {anchorStart}technical support{anchorEnd}.'), // eslint-disable-line max-len
{
email: this.model.get(this.options.emailAttribute),
anchorStart: HtmlUtils.HTML(
StringUtils.interpolate(
'<a href="{passwordResetSupportUrl}">', {
passwordResetSupportUrl: this.options.passwordResetSupportUrl
}
)
),
anchorEnd: HtmlUtils.HTML('</a>')
}
)
);
}
......@@ -209,7 +218,7 @@
saveValue: function() {
if (this.persistChanges === true) {
var attributes = {},
value = this.fieldValue() ? [{'code': this.fieldValue()}] : [];
value = this.fieldValue() ? [{code: this.fieldValue()}] : [];
attributes[this.options.valueAttribute] = value;
this.saveAttributes(attributes);
}
......
......@@ -41,6 +41,7 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str
fieldsData,
ordersHistoryData,
authData,
'${ password_reset_support_link | n, js_escaped_string }',
'${ user_accounts_api_url | n, js_escaped_string }',
'${ user_preferences_api_url | n, js_escaped_string }',
${ user.id | n, dump_js_escaped_json },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment