chore(build): Adding jscs validateIndentation rule

Conflicts:
	app/tests/spec/lib/fxa-client.js
This commit is contained in:
Peter deHaan 2014-09-05 15:21:30 -07:00
Родитель ca64752fd3
Коммит bc2e215047
40 изменённых файлов: 614 добавлений и 618 удалений

Просмотреть файл

@ -14,6 +14,7 @@
"requireSpaceAfterPrefixUnaryOperators": ["~"],
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"requireSpacesInConditionalExpression": true,
"validateIndentation": 2,
"validateLineBreaks": "LF",
"validateQuoteMarks": true,
"validateJSDoc": {

Просмотреть файл

@ -46,8 +46,6 @@ function (
Relier
) {
function isMetricsCollectionEnabled (sampleRate) {
return Math.random() <= sampleRate;
}
@ -76,10 +74,10 @@ function (
// fetch both config and translations in parallel to speed up load.
return p.all([
this.initializeConfig(),
this.initializeL10n()
])
.then(_.bind(this.allResourcesReady, this));
this.initializeConfig(),
this.initializeL10n()
])
.then(_.bind(this.allResourcesReady, this));
},
initializeConfig: function () {

Просмотреть файл

@ -112,45 +112,45 @@ function (_, FxaClient, $, p, Session, AuthErrors, Constants, Channels) {
options = options || {};
return p().then(function() {
// If we already verified in signUp that we can link with
// the desktop, don't do it again. Otherwise,
// make the call over to the Desktop code to ask if
// we can allow the linking.
if (!options.verifiedCanLinkAccount) {
return self._checkForDesktopSyncRelinkWarning(email);
}
return;
})
.then(_.bind(self._getClientAsync, self))
.then(function (client) {
return client.signIn(email, password, { keys: true });
})
.then(function (accountData) {
// get rid of any old data.
Session.clear();
// If we already verified in signUp that we can link with
// the desktop, don't do it again. Otherwise,
// make the call over to the Desktop code to ask if
// we can allow the linking.
if (!options.verifiedCanLinkAccount) {
return self._checkForDesktopSyncRelinkWarning(email);
}
return;
})
.then(_.bind(self._getClientAsync, self))
.then(function (client) {
return client.signIn(email, password, { keys: true });
})
.then(function (accountData) {
// get rid of any old data.
Session.clear();
var updatedSessionData = {
email: email,
uid: accountData.uid,
unwrapBKey: accountData.unwrapBKey,
keyFetchToken: accountData.keyFetchToken,
sessionToken: accountData.sessionToken,
sessionTokenContext: Session.context,
customizeSync: options.customizeSync
};
var updatedSessionData = {
email: email,
uid: accountData.uid,
unwrapBKey: accountData.unwrapBKey,
keyFetchToken: accountData.keyFetchToken,
sessionToken: accountData.sessionToken,
sessionTokenContext: Session.context,
customizeSync: options.customizeSync
};
Session.set(updatedSessionData);
// Skipping the relink warning is only relevant to the channel
// communication with the Desktop browser. It may have been
// done during a sign up flow.
updatedSessionData.verifiedCanLinkAccount = true;
Session.set(updatedSessionData);
// Skipping the relink warning is only relevant to the channel
// communication with the Desktop browser. It may have been
// done during a sign up flow.
updatedSessionData.verifiedCanLinkAccount = true;
return Channels.sendExpectResponse('login', updatedSessionData, {
channel: self._channel
}).then(function () {
return accountData;
});
});
return Channels.sendExpectResponse('login', updatedSessionData, {
channel: self._channel
}).then(function () {
return accountData;
});
});
},

Просмотреть файл

@ -5,12 +5,12 @@
'use strict';
require([
'./require_config'
],
function (RequireConfig) {
// Ensure config is loaded before trying to load any other scripts.
require(['./lib/app-start'], function (AppStart) {
var appStart = new AppStart();
appStart.startApp();
});
'./require_config'
],
function (RequireConfig) {
// Ensure config is loaded before trying to load any other scripts.
require(['./lib/app-start'], function (AppStart) {
var appStart = new AppStart();
appStart.startApp();
});
});

Просмотреть файл

@ -54,13 +54,13 @@ function (_, BaseView, FormView, Template, Session, PasswordMixin, FloatingPlace
var self = this;
return this.fxaClient.isPasswordResetComplete(this.token)
.then(function (isComplete) {
self._isLinkExpired = isComplete;
if (isComplete) {
self.logEvent('complete_reset_password:link_expired');
}
return true;
});
.then(function (isComplete) {
self._isLinkExpired = isComplete;
if (isComplete) {
self.logEvent('complete_reset_password:link_expired');
}
return true;
});
},
afterRender: function() {

Просмотреть файл

@ -52,12 +52,12 @@ define([
}
return Channels.sendExpectResponse(message, data, {
window: self.window,
channel: self.channel
}).then(null, function (err) {
self.clearTimeout(self._expectResponseTimeout);
throw err;
});
window: self.window,
channel: self.channel
}).then(null, function (err) {
self.clearTimeout(self._expectResponseTimeout);
throw err;
});
}
/**
@ -151,9 +151,9 @@ define([
finishOAuthFlowDifferentBrowser: function () {
return _notifyChannel.call(this, 'oauth_complete', {
redirect: this.serviceRedirectURI,
error: RP_DIFFERENT_BROWSER_ERROR_CODE
});
redirect: this.serviceRedirectURI,
error: RP_DIFFERENT_BROWSER_ERROR_CODE
});
},
finishOAuthFlow: buttonProgressIndicator(function (viewOptions) {

Просмотреть файл

@ -23,9 +23,9 @@ function (_, p, SignInView, ServiceMixin) {
beforeRender: function() {
var self = this;
return p().then(function () {
return SignInView.prototype.beforeRender.call(self);
})
.then(_.bind(this.setServiceInfo, this));
return SignInView.prototype.beforeRender.call(self);
})
.then(_.bind(this.setServiceInfo, this));
},
afterRender: function() {

Просмотреть файл

@ -31,9 +31,9 @@ function (_, p, BaseView, SignUpView, ServiceMixin) {
beforeRender: function() {
var self = this;
return p().then(function () {
return SignUpView.prototype.beforeRender.call(self);
})
.then(_.bind(this.setServiceInfo, this));
return SignUpView.prototype.beforeRender.call(self);
})
.then(_.bind(this.setServiceInfo, this));
},
afterRender: function() {

Просмотреть файл

@ -5,111 +5,111 @@
'use strict';
define([
'jquery',
'underscore',
'views/form',
'stache!templates/settings/avatar_change',
'lib/session',
'lib/auth-errors'
],
function ($, _, FormView, Template, Session, AuthErrors) {
'jquery',
'underscore',
'views/form',
'stache!templates/settings/avatar_change',
'lib/session',
'lib/auth-errors'
],
function ($, _, FormView, Template, Session, AuthErrors) {
// a blank 1x1 png
var pngSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==';
// a blank 1x1 png
var pngSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==';
var View = FormView.extend({
// user must be authenticated to see Settings
mustAuth: true,
var View = FormView.extend({
// user must be authenticated to see Settings
mustAuth: true,
template: Template,
className: 'avatar_change',
template: Template,
className: 'avatar_change',
events: {
'click #file': 'filePicker',
'click .remove': 'remove',
'change #imageLoader': 'fileSet'
},
events: {
'click #file': 'filePicker',
'click .remove': 'remove',
'change #imageLoader': 'fileSet'
},
initialize: function () {
Session.clear('cropImgWidth');
Session.clear('cropImgHeight');
// override in tests
this.FileReader = FileReader;
},
initialize: function () {
Session.clear('cropImgWidth');
Session.clear('cropImgHeight');
// override in tests
this.FileReader = FileReader;
},
afterRender: function () {
var wrapper = $('<div/>').css({ height: 0, width: 0, 'overflow': 'hidden' });
this.$(':file').wrap(wrapper);
},
afterRender: function () {
var wrapper = $('<div/>').css({ height: 0, width: 0, 'overflow': 'hidden' });
this.$(':file').wrap(wrapper);
},
context: function () {
return {
avatar: Session.avatar
};
},
context: function () {
return {
avatar: Session.avatar
};
},
remove: function () {
Session.clear('avatar');
this.navigate('settings/avatar');
},
remove: function () {
Session.clear('avatar');
this.navigate('settings/avatar');
},
filePicker: function () {
// skip the file picker if this is an automater browser
if (this.automatedBrowser) {
var self = this;
require(['draggable', 'touch-punch'], function () {
Session.set('cropImgSrc', pngSrc);
Session.set('cropImgWidth', 1);
Session.set('cropImgHeight', 1);
self.navigate('settings/avatar/crop');
});
return;
}
this.$('#imageLoader').click();
},
fileSet: function (e) {
filePicker: function () {
// skip the file picker if this is an automater browser
if (this.automatedBrowser) {
var self = this;
var file = e.target.files[0];
require(['draggable', 'touch-punch'], function () {
Session.set('cropImgSrc', pngSrc);
Session.set('cropImgWidth', 1);
Session.set('cropImgHeight', 1);
// Define our callbacks here to avoid a circular DOM reference
var imgOnload = function () {
// Store the width and height for the cropper view
Session.set('cropImgWidth', this.width);
Session.set('cropImgHeight', this.height);
require(['draggable', 'touch-punch'], function () {
self.navigate('settings/avatar/crop');
});
};
var imgOnerrer = function () {
self.navigate('settings/avatar', {
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
});
};
if (file.type.match('image.*')) {
var reader = new self.FileReader();
reader.onload = function (event) {
var src = event.target.result;
Session.set('cropImgSrc', src);
var img = new Image();
img.src = src;
img.onload = imgOnload;
img.onerror = imgOnerrer;
};
reader.readAsDataURL(file);
} else {
self.navigate('settings/avatar', {
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
});
}
self.navigate('settings/avatar/crop');
});
return;
}
});
this.$('#imageLoader').click();
},
return View;
fileSet: function (e) {
var self = this;
var file = e.target.files[0];
// Define our callbacks here to avoid a circular DOM reference
var imgOnload = function () {
// Store the width and height for the cropper view
Session.set('cropImgWidth', this.width);
Session.set('cropImgHeight', this.height);
require(['draggable', 'touch-punch'], function () {
self.navigate('settings/avatar/crop');
});
};
var imgOnerrer = function () {
self.navigate('settings/avatar', {
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
});
};
if (file.type.match('image.*')) {
var reader = new self.FileReader();
reader.onload = function (event) {
var src = event.target.result;
Session.set('cropImgSrc', src);
var img = new Image();
img.src = src;
img.onload = imgOnload;
img.onerror = imgOnerrer;
};
reader.readAsDataURL(file);
} else {
self.navigate('settings/avatar', {
error: AuthErrors.toMessage('UNUSABLE_IMAGE')
});
}
}
});
return View;
});

Просмотреть файл

@ -66,13 +66,13 @@ function (_, p, BaseView, FormView, SignInTemplate, Constants, Session, Password
beforeRender: function() {
var self = this;
return p().then(function () {
return FormView.prototype.beforeRender.call(self);
})
.then(function () {
if (self.hasService() && self.isSync()) {
return self.setServiceInfo();
}
});
return FormView.prototype.beforeRender.call(self);
})
.then(function () {
if (self.hasService() && self.isSync()) {
return self.setServiceInfo();
}
});
},
submit: function () {

Просмотреть файл

@ -67,13 +67,13 @@ function (_, p, BaseView, FormView, Template, Session, PasswordMixin, AuthErrors
var self = this;
return p().then(function () {
return FormView.prototype.beforeRender.call(self);
})
.then(function () {
if (self.hasService() && self.isSync()) {
return self.setServiceInfo();
}
});
return FormView.prototype.beforeRender.call(self);
})
.then(function () {
if (self.hasService() && self.isSync()) {
return self.setServiceInfo();
}
});
},
// afterRender fucnction to handle select-row hack (issue 822)
@ -189,30 +189,30 @@ function (_, p, BaseView, FormView, Template, Session, PasswordMixin, AuthErrors
var self = this;
return this.fxaClient.signUp(email, password, {
customizeSync: customizeSync,
preVerifyToken: preVerifyToken
}).then(_.bind(self.onSignUpSuccess, self))
.then(null, function (err) {
// Account already exists. No attempt is made at signing the
// user in directly, instead, point the user to the signin page
// where the entered email/password will be prefilled.
if (AuthErrors.is(err, 'ACCOUNT_ALREADY_EXISTS')) {
return self._suggestSignIn(err);
} else if (AuthErrors.is(err, 'USER_CANCELED_LOGIN')) {
self.logEvent('login:canceled');
// if user canceled login, just stop
return;
} else if (self._preVerifyToken && AuthErrors.is(err, 'INVALID_VERIFICATION_CODE')) {
// The token was invalid and the auth server could not pre-verify
// the user. Now, just create a new user and force them to verify
// their email.
self._preVerifyToken = null;
return self._createAccount();
}
customizeSync: customizeSync,
preVerifyToken: preVerifyToken
}).then(_.bind(self.onSignUpSuccess, self))
.then(null, function (err) {
// Account already exists. No attempt is made at signing the
// user in directly, instead, point the user to the signin page
// where the entered email/password will be prefilled.
if (AuthErrors.is(err, 'ACCOUNT_ALREADY_EXISTS')) {
return self._suggestSignIn(err);
} else if (AuthErrors.is(err, 'USER_CANCELED_LOGIN')) {
self.logEvent('login:canceled');
// if user canceled login, just stop
return;
} else if (self._preVerifyToken && AuthErrors.is(err, 'INVALID_VERIFICATION_CODE')) {
// The token was invalid and the auth server could not pre-verify
// the user. Now, just create a new user and force them to verify
// their email.
self._preVerifyToken = null;
return self._createAccount();
}
// re-throw error, it will be handled at a lower level.
throw err;
});
// re-throw error, it will be handled at a lower level.
throw err;
});
},
onSignUpSuccess: function(accountData) {

Просмотреть файл

@ -112,9 +112,9 @@ function (chai, AuthErrors) {
describe('is', function () {
it('checks if an error returned from the server is of a given type',
function () {
assert.isTrue(AuthErrors.is({ errno: 102 }, 'UNKNOWN_ACCOUNT'));
assert.isFalse(AuthErrors.is({ errno: 103 }, 'UNKNOWN_ACCOUNT'));
});
assert.isTrue(AuthErrors.is({ errno: 102 }, 'UNKNOWN_ACCOUNT'));
assert.isFalse(AuthErrors.is({ errno: 103 }, 'UNKNOWN_ACCOUNT'));
});
});
});
});

Просмотреть файл

@ -75,12 +75,12 @@ function (chai, WindowMock, Session, FxDesktopChannel, TestHelpers) {
it('registers a callback to be called when the browser sends ' +
'the registered message', function (done) {
channel.on('call-the-callback', function () {
done();
});
channel.on('call-the-callback', function () {
done();
});
dispatchEvent('call-the-callback');
});
dispatchEvent('call-the-callback');
});
});
});
});

Просмотреть файл

@ -6,64 +6,63 @@
define([
'underscore',
'chai',
'router',
'views/sign_in',
'lib/channels/web',
'/tests/mocks/window.js'
],
function (_, chai, Router, View, WebChannel, WindowMock) {
var assert = chai.assert;
'underscore',
'chai',
'router',
'views/sign_in',
'lib/channels/web',
'/tests/mocks/window.js'
],
function (_, chai, Router, View, WebChannel, WindowMock) {
var assert = chai.assert;
describe('lib/channel/web', function () {
it('requires an id', function (done) {
try {
new WebChannel();
} catch (e) {
assert.equal(e.message, 'WebChannel must have an id');
done();
}
describe('lib/channel/web', function () {
it('requires an id', function (done) {
try {
new WebChannel();
} catch (e) {
assert.equal(e.message, 'WebChannel must have an id');
done();
}
});
describe('send', function () {
var windowMock;
var channel;
beforeEach(function () {
windowMock = new WindowMock();
});
describe('send', function () {
var windowMock;
var channel;
beforeEach(function () {
windowMock = new WindowMock();
it('sends an event with a callback', function (done) {
channel = new WebChannel('MyChannel', windowMock);
channel.init({
window: windowMock
});
it('sends an event with a callback', function (done) {
channel = new WebChannel('MyChannel', windowMock);
channel.init({
window: windowMock
});
channel.send('after_render', {}, function (err, response) {
assert.notOk(err);
assert.ok(windowMock.dispatchedEvents['after_render']);
done();
});
});
channel.send('after_render', {}, function (err, response) {
assert.notOk(err);
assert.ok(windowMock.dispatchedEvents['after_render']);
done();
});
it('throws an error if dispatchEvent fails', function (done) {
windowMock.dispatchEvent = function () {
throw new Error('Not supported');
};
channel = new WebChannel('MyChannel', windowMock);
channel.init({
window: windowMock
});
it('throws an error if dispatchEvent fails', function (done) {
windowMock.dispatchEvent = function () {
throw new Error('Not supported');
};
channel = new WebChannel('MyChannel', windowMock);
channel.init({
window: windowMock
});
channel.send('after_render', {}, function (err, response) {
assert.equal(err.message, 'Not supported');
assert.notOk(response);
done();
}
);
channel.send('after_render', {}, function (err, response) {
assert.equal(err.message, 'Not supported');
assert.notOk(response);
done();
});
});
});
});
});

Просмотреть файл

@ -155,7 +155,7 @@ function (chai, $, sinon, p, ChannelMock, testHelpers,
});
it('signUp existing unverified user with different password signs ' +
'user up again', function () {
'user up again', function () {
return client.signUp(email, password)
.then(function () {
return client.signUp(email, 'different_password');
@ -182,15 +182,15 @@ function (chai, $, sinon, p, ChannelMock, testHelpers,
});
return client.signUp(email, password, {
preVerifyToken: preVerifyToken
})
.then(function () {
assert.isTrue(realClient.signUp.calledWith(trim(email), password, {
preVerifyToken: preVerifyToken,
keys: true
}));
assert.isTrue(realClient.signIn.called);
});
preVerifyToken: preVerifyToken
})
.then(function () {
assert.isTrue(realClient.signUp.calledWith(trim(email), password, {
preVerifyToken: preVerifyToken,
keys: true
}));
assert.isTrue(realClient.signIn.called);
});
});
});

Просмотреть файл

@ -63,7 +63,7 @@ function (chai, $, testHelpers, sinon,
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[200, { 'Content-Type': 'application/json' },
'{ "redirect": "' + redirect + '" }']);
'{ "redirect": "' + redirect + '" }']);
return client.getCode(params)
.then(function (result) {
@ -93,127 +93,125 @@ function (chai, $, testHelpers, sinon,
})]);
return client.getCode(params)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'INCORRECT_REDIRECT'));
return client.getCode(params)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'INCORRECT_REDIRECT'));
});
});
});
});
describe('getClientInfo', function () {
var clientId = 'clientId';
describe('getClientInfo', function () {
var clientId = 'clientId';
it('normally response with a name and imageUri', function () {
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
[200, { 'Content-Type': 'application/json' },
it('normally response with a name and imageUri', function () {
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
[200, { 'Content-Type': 'application/json' },
'{ "name": "MozRP", "imageUri": "https://mozilla.org/firefox.png" }']);
return client.getClientInfo(clientId)
.then(function (result) {
assert.ok(result);
assert.equal(result.name, 'MozRP');
return client.getClientInfo(clientId)
.then(function (result) {
assert.ok(result);
assert.equal(result.name, 'MozRP');
});
});
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
var clientId = 'clientId';
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
[0, {}, '']);
return client.getClientInfo(clientId)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
});
});
it('converts returned errors to OAuth error objects', function () {
var clientId = 'clientId';
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
[400, { 'Content-Type': 'application/json' },
JSON.stringify({
errno: OAuthErrors.toCode('EXPIRED_CODE'),
code: 400
})]);
return client.getClientInfo(clientId)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'EXPIRED_CODE'));
});
});
});
describe('getToken', function () {
it('normally responds with a token', function () {
var token = 'access token';
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[200, { 'Content-Type': 'application/json' },
'{ "scope": "profile", "token_type": "bearer", "access_token": "' + token + '" }']);
var params = {
assertion: 'assertion',
client_id: 'deadbeef',
scope: 'profile'
};
return client.getToken(params)
.then(function (result) {
assert.ok(result);
assert.equal(result.access_token, 'access token');
});
});
});
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
var clientId = 'clientId';
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[0, {}, '']);
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
[0, {}, '']);
var params = {
assertion: 'assertion',
client_id: 'deadbeef',
scope: 'profile'
};
return client.getClientInfo(clientId)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
return client.getToken(params)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
});
});
});
it('converts returned errors to OAuth error objects', function () {
var clientId = 'clientId';
it('converts returned errors to OAuth error objects', function () {
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[400, { 'Content-Type': 'application/json' },
JSON.stringify({
errno: OAuthErrors.toCode('INVALID_ASSERTION'),
code: 400
})]);
server.respondWith('GET', OAUTH_URL + '/v1/client/' + clientId,
[400, { 'Content-Type': 'application/json' },
JSON.stringify({
errno: OAuthErrors.toCode('EXPIRED_CODE'),
code: 400
})]);
var params = {
assertion: 'assertion',
client_id: 'deadbeef',
scope: 'profile'
};
return client.getClientInfo(clientId)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'EXPIRED_CODE'));
return client.getToken(params)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'INVALID_ASSERTION'));
});
});
});
});
});
});
describe('getToken', function () {
it('normally responds with a token', function () {
var token = 'access token';
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[200, { 'Content-Type': 'application/json' },
'{ "scope": "profile", "token_type": "bearer", "access_token": "' + token + '" }']);
var params = {
assertion: 'assertion',
client_id: 'deadbeef',
scope: 'profile'
};
return client.getToken(params)
.then(function (result) {
assert.ok(result);
assert.equal(result.access_token, 'access token');
});
});
it('responds with a SERVICE_UNAVAILABLE error if the service is unavailable', function () {
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[0, {}, '']);
var params = {
assertion: 'assertion',
client_id: 'deadbeef',
scope: 'profile'
};
return client.getToken(params)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'SERVICE_UNAVAILABLE'));
});
});
it('converts returned errors to OAuth error objects', function () {
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[400, { 'Content-Type': 'application/json' },
JSON.stringify({
errno: OAuthErrors.toCode('INVALID_ASSERTION'),
code: 400
})]);
var params = {
assertion: 'assertion',
client_id: 'deadbeef',
scope: 'profile'
};
return client.getToken(params)
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(OAuthErrors.is(err, 'INVALID_ASSERTION'));
});
});
});
});
});
});

Просмотреть файл

@ -56,8 +56,8 @@ function (chai, OAuthErrors) {
describe('is', function () {
it('checks if an error returned from the server is of a given type',
function () {
assert.isTrue(OAuthErrors.is({ errno: 101 }, 'UNKNOWN_CLIENT'));
});
assert.isTrue(OAuthErrors.is({ errno: 101 }, 'UNKNOWN_CLIENT'));
});
});
});
});

Просмотреть файл

@ -50,7 +50,7 @@ function (chai, $, sinon,
it('normally responds with profile', function () {
server.respondWith('GET', PROFILE_URL + '/v1/profile',
[200, { 'Content-Type': 'application/json' },
'{ "uid": "' + UID + '", "email": "' + EMAIL + '" }']);
'{ "uid": "' + UID + '", "email": "' + EMAIL + '" }']);
return client.getProfile()
.then(function (result) {
@ -80,31 +80,31 @@ function (chai, $, sinon,
code: 403
})]);
return client.getProfile()
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(ProfileClient.Errors.is(err, 'UNAUTHORIZED'));
return client.getProfile()
.then(function (result) {
assert.fail('unexpected success');
}, function (err) {
assert.isTrue(ProfileClient.Errors.is(err, 'UNAUTHORIZED'));
});
});
});
});
describe('getRemoteImage', function () {
it('normally responds with remote image', function () {
var src = encodeURIComponent('http://example.com/logo.jpg');
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
[200, { 'Content-Type': 'text/plain' },
describe('getRemoteImage', function () {
it('normally responds with remote image', function () {
var src = encodeURIComponent('http://example.com/logo.jpg');
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
[200, { 'Content-Type': 'text/plain' },
'data:image/jpeg;base64,ohhai']);
return client.getRemoteImage('http://example.com/logo.jpg')
.then(function (result) {
assert.equal(result, 'data:image/jpeg;base64,ohhai');
});
return client.getRemoteImage('http://example.com/logo.jpg')
.then(function (result) {
assert.equal(result, 'data:image/jpeg;base64,ohhai');
});
});
});
});
});
});
});

Просмотреть файл

@ -64,11 +64,11 @@ function (chai, _, Backbone, Router, SignInView, SignUpView, ReadyView, Session,
it('preserves window search parameters across screen transition',
function () {
windowMock.location.search = '?context=' + Constants.FX_DESKTOP_CONTEXT;
router.navigate('/forgot');
assert.equal(navigateUrl, '/forgot?context=' + Constants.FX_DESKTOP_CONTEXT);
assert.deepEqual(navigateOptions, { trigger: true });
});
windowMock.location.search = '?context=' + Constants.FX_DESKTOP_CONTEXT;
router.navigate('/forgot');
assert.equal(navigateUrl, '/forgot?context=' + Constants.FX_DESKTOP_CONTEXT);
assert.deepEqual(navigateOptions, { trigger: true });
});
});
describe('redirectToSignupOrSettings', function () {

Просмотреть файл

@ -21,11 +21,11 @@ function (chai, Translator) {
[null, '⊥ɥǝɹǝ ʍɐs ɐ dɹoqʅǝɯ ʍıʇɥ ʎonɹ sıƃund ʅıuʞ˙ Hɐs ʇɥıs ɐppɹǝss ɐʅɹǝɐpʎ qǝǝu ɹǝƃısʇǝɹǝp¿'],
'Error encountered trying to register: %(email)s.': [null,
'Ǝɹɹoɹ ǝuɔonuʇǝɹǝp ʇɹʎıuƃ ʇo ɹǝƃısʇɹɐʇıou: %(email)s˙'],
'Ǝɹɹoɹ ǝuɔonuʇǝɹǝp ʇɹʎıuƃ ʇo ɹǝƃısʇɹɐʇıou: %(email)s˙'],
// use one direct translation to prepare for simpler json files.
'%s, Persona requires cookies to remember you.':
'%s, Ԁǝɹsouɐ ɹǝbnıɹǝs ɔooʞıǝs ʇo ɹǝɯǝɯqǝɹ ʎon˙'
'%s, Ԁǝɹsouɐ ɹǝbnıɹǝs ɔooʞıǝs ʇo ɹǝɯǝɯqǝɹ ʎon˙'
};
describe('lib/translator', function () {

Просмотреть файл

@ -17,8 +17,8 @@ function (chai, _, Url) {
describe('searchParam', function () {
it('returns a parameter from window.location.search, if it exists',
function() {
assert.equal(Url.searchParam('color', '?color=green'), 'green');
});
assert.equal(Url.searchParam('color', '?color=green'), 'green');
});
it('returns undefined if parameter does not exist', function() {
assert.isUndefined(Url.searchParam('animal', '?color=green'));
@ -34,18 +34,18 @@ function (chai, _, Url) {
it('returns all parameters from window.location.search, if no whitelist specified',
function() {
var params = Url.searchParams(search);
assert.equal(params.color, 'green');
assert.equal(params.email, 'testuser@testuser.com');
});
var params = Url.searchParams(search);
assert.equal(params.color, 'green');
assert.equal(params.email, 'testuser@testuser.com');
});
it('only returns whitelisted parameters from window.location.search, if whitelist specified',
function() {
var params = Url.searchParams(search, ['color', 'notDefined']);
assert.equal(params.color, 'green');
assert.isFalse('email' in params);
assert.isFalse('notDefined' in params);
});
var params = Url.searchParams(search, ['color', 'notDefined']);
assert.equal(params.color, 'green');
assert.isFalse('email' in params);
assert.isFalse('notDefined' in params);
});
});

Просмотреть файл

@ -155,7 +155,7 @@ function (chai, _, $, AuthErrors, FxaClient, View, RouterMock, TestHelpers, Sess
});
});
it('changes from old to new password, keeps sessionTokenContext', function () {
it('changes from old to new password, keeps sessionTokenContext', function () {
$('#old_password').val('password');
$('#new_password').val('new_password');

Просмотреть файл

@ -53,7 +53,7 @@ function (chai, $, View, Session, FxaClient, WindowMock, RouterMock) {
it('shows no avatar if Session.avatar is undefined', function (done) {
Session.set('forceEmail', 'a@a.com');
assert.isNull(view.context().avatar);
return view.render()
.then(function () {
assert.notOk(view.$('.avatar-view img').length);

Просмотреть файл

@ -61,7 +61,7 @@ function (chai, $, View, Session, FxaClient, WindowMock, RouterMock, OAuthServer
describe('render', function () {
it('displays oAuth client name', function () {
return view.render()
.then(function () {
.then(function () {
assert.include($('#fxa-signin-header').text(), CLIENT_NAME);
// also make sure link is correct
assert.equal($('.sign-up').attr('href'), '/oauth/signup');

Просмотреть файл

@ -21,16 +21,16 @@ define([
function (chai, _, $, p, sinon, View, RouterMock, Session, Assertion, Constants, AuthErrors) {
var assert = chai.assert;
// 1x1 jpeg
var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBA' +
'MFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMD' +
'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEB' +
'AxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQ' +
'RBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVF' +
'VWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx' +
'8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI' +
'CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChY' +
'kNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkp' +
'OUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q==';
var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBA' +
'MFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMD' +
'AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEB' +
'AxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQ' +
'RBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVF' +
'VWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx' +
'8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI' +
'CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChY' +
'kNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkp' +
'OUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q==';
// These URLs don't depend on our actual configuration; the servers are mocked out.
var PROFILE_URL = 'http://127.0.0.1:1111';
@ -104,8 +104,7 @@ var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAw
server.respondWith('POST', OAUTH_URL + '/v1/authorization',
[200, { 'Content-Type': 'application/json' },
'{ "scope": "profile", "token_type": "bearer", "access_token": "token" }']);
'{ "scope": "profile", "token_type": "bearer", "access_token": "token" }']);
Assertion.generate = function () {
return p('assertion');
@ -126,51 +125,50 @@ var jpgSrcData = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAw
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
[200, { 'Content-Type': 'text/plain' },
'data:image/jpeg;base64,']);
'data:image/jpeg;base64,']);
view.render()
.then(function () {
view.router.on('navigate', function () {
try {
assert.equal(routerMock.page, 'settings/avatar');
assert.equal(view.ephemeralMessages.get('error'), AuthErrors.toMessage('UNUSABLE_IMAGE'));
done();
} catch (e) {
return done(e);
}
});
view.render()
.then(function () {
view.router.on('navigate', function () {
try {
assert.equal(routerMock.page, 'settings/avatar');
assert.equal(view.ephemeralMessages.get('error'), AuthErrors.toMessage('UNUSABLE_IMAGE'));
done();
} catch (e) {
return done(e);
}
});
view.$('.url').val('http://example.com/logo.jpg');
view.submit();
})
.fail(done);
view.$('.url').val('http://example.com/logo.jpg');
view.submit();
})
.fail(done);
});
it('submits', function (done) {
var src = encodeURIComponent('http://example.com/logo.jpg');
server.respondWith('GET', PROFILE_URL + '/v1/remote_image/' + src,
[200, { 'Content-Type': 'text/plain' },
jpgSrcData]);
[200, { 'Content-Type': 'text/plain' }, jpgSrcData]);
view.render()
.then(function () {
view.router.on('navigate', function () {
try {
assert.equal(routerMock.page, 'settings/avatar/crop');
assert.include(Session.cropImgSrc, jpgSrcData);
assert.equal(Session.cropImgWidth, 1);
assert.equal(Session.cropImgHeight, 1);
done();
} catch (e) {
return done(e);
}
});
view.render()
.then(function () {
view.router.on('navigate', function () {
try {
assert.equal(routerMock.page, 'settings/avatar/crop');
assert.include(Session.cropImgSrc, jpgSrcData);
assert.equal(Session.cropImgWidth, 1);
assert.equal(Session.cropImgHeight, 1);
done();
} catch (e) {
return done(e);
}
});
view.$('.url').val('http://example.com/logo.jpg');
view.submit();
})
.fail(done);
view.$('.url').val('http://example.com/logo.jpg');
view.submit();
})
.fail(done);
});
});

Просмотреть файл

@ -27,34 +27,35 @@ module.exports = function (grunt) {
grunt.task.renameTask('connect_fonts', 'do_connect_fonts');
grunt.task.registerTask('connect_fonts',
'configure connect fonts based on the currently selected config', function () {
// server config is not available on startup and is set in the
// selectconfig task. configure_connect_fonts should be run after
// selectconfig and before connect_fonts.
var fontsDisabled = grunt.config.get('server.i18n.fonts.unsupportedLanguages');
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages')
.filter(function (lang) {
return fontsDisabled.indexOf(lang) === -1;
});
'configure connect fonts based on the currently selected config',
function () {
// server config is not available on startup and is set in the
// selectconfig task. configure_connect_fonts should be run after
// selectconfig and before connect_fonts.
var fontsDisabled = grunt.config.get('server.i18n.fonts.unsupportedLanguages');
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages')
.filter(function (lang) {
return fontsDisabled.indexOf(lang) === -1;
});
grunt.config('do_connect_fonts', {
dist: {
options: {
fontPacks: fontPacks,
fontNames: fontNamesNeeded,
// languages will be configured in configure_connect_fonts
languages: supportedLanguages,
dest: '<%= yeoman.app %>/styles/fonts',
destFileName: function (root, language) {
// items on disk are stored by locale, not language.
return path.join(root, i18n.localeFrom(language) + '.css');
grunt.config('do_connect_fonts', {
dist: {
options: {
fontPacks: fontPacks,
fontNames: fontNamesNeeded,
// languages will be configured in configure_connect_fonts
languages: supportedLanguages,
dest: '<%= yeoman.app %>/styles/fonts',
destFileName: function (root, language) {
// items on disk are stored by locale, not language.
return path.join(root, i18n.localeFrom(language) + '.css');
}
}
}
}
}
});
});
grunt.task.run(['do_connect_fonts']);
});
grunt.task.run(['do_connect_fonts']);
});
grunt.config('connect_fonts_copy', {
dist: {

Просмотреть файл

@ -12,7 +12,7 @@ module.exports = function (grunt) {
'!<%= yeoman.app %>/scripts/vendor/**'
],
options: {
config: '.jscs.json'
config: '.jscsrc'
}
});
};

Просмотреть файл

@ -45,26 +45,26 @@ module.exports = function (grunt) {
grunt.registerTask('l10n-compile-templates',
'Generate localized versions of the static pages', function () {
'Generate localized versions of the static pages', function () {
var done = this.async();
var done = this.async();
var i18n = require('../server/lib/i18n')(grunt.config.get('server.i18n'));
var i18n = require('../server/lib/i18n')(grunt.config.get('server.i18n'));
// server config is set in the selectconfig task
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages');
defaultLang = grunt.config.get('server.i18n.defaultLang');
// server config is set in the selectconfig task
var supportedLanguages = grunt.config.get('server.i18n.supportedLanguages');
defaultLang = grunt.config.get('server.i18n.defaultLang');
templateSrc = grunt.config.get('yeoman.page_template_src');
templateDest = grunt.config.get('yeoman.page_template_dist');
templateSrc = grunt.config.get('yeoman.page_template_src');
templateDest = grunt.config.get('yeoman.page_template_dist');
// Legal templates have already been generated and placed in the template destination directory.
var getTemplate = legalTemplates(i18n, templateDest);
// Legal templates have already been generated and placed in the template destination directory.
var getTemplate = legalTemplates(i18n, templateDest);
// Create a cache of the templates so we can reference them synchronously later
Promise.settle(supportedLanguages.map(function (lang) {
// Create a cache of the templates so we can reference them synchronously later
Promise.settle(supportedLanguages.map(function (lang) {
return Promise.all([
return Promise.all([
getTemplate('terms', lang, defaultLang),
getTemplate('privacy', lang, defaultLang)
])
@ -75,14 +75,14 @@ module.exports = function (grunt) {
};
});
})).then(function () {
supportedLanguages.forEach(function (lang) {
generatePagesForLanguage(i18n, lang);
});
done();
}).then(null, done);
})).then(function () {
supportedLanguages.forEach(function (lang) {
generatePagesForLanguage(i18n, lang);
});
done();
}).then(null, done);
});
});
function generatePagesForLanguage(i18n, language) {
@ -93,10 +93,9 @@ module.exports = function (grunt) {
grunt.file.recurse(templateSrc,
function (srcPath, rootDir, subDir, fileName) {
var destPath = path.join(destRoot, (subDir || ''), fileName);
generatePage(srcPath, destPath, context);
});
var destPath = path.join(destRoot, (subDir || ''), fileName);
generatePage(srcPath, destPath, context);
});
}
function generatePage(srcPath, destPath, context) {

Просмотреть файл

@ -7,14 +7,14 @@ module.exports = function (grunt) {
'use strict';
grunt.registerTask('l10n-generate-tos-pp',
'Generate translated TOS/PP agreement partial templates',
function () {
'Generate translated TOS/PP agreement partial templates',
function () {
grunt.task.run([
'clean:tos_pp',
'replace:tos_pp',
'marked:tos_pp'
]);
});
grunt.task.run([
'clean:tos_pp',
'replace:tos_pp',
'marked:tos_pp'
]);
});
};

Просмотреть файл

@ -93,7 +93,7 @@ function makeApp() {
// workaround for reserved word bug:
// https://github.com/marijnh/acorn/issues/85
app.use(express['static'](STATIC_DIRECTORY, {
maxAge: config.get('static_max_age')
maxAge: config.get('static_max_age')
}));
// it's a four-oh-four not found.
@ -116,8 +116,8 @@ function listen(theApp) {
// Development only... Ops runs this behind nginx
port = config.get('port');
var tlsoptions = {
key: fs.readFileSync(config.get('key_path')),
cert: fs.readFileSync(config.get('cert_path'))
key: fs.readFileSync(config.get('key_path')),
cert: fs.readFileSync(config.get('cert_path'))
};
https.createServer(tlsoptions, app).listen(port);

Просмотреть файл

@ -169,16 +169,18 @@ var conf = module.exports = convict({
format: Array,
// the big list of locales is specified so the production build script
// can build all the locales before config/production.json is written.
default: ['af', 'an', 'ar', 'as', 'ast', 'be', 'bg', 'bn-BD', 'bn-IN', 'br',
'bs', 'ca', 'cs', 'cy', 'da', 'de', 'dsb', 'el', 'en-GB', 'en-US', 'en-ZA',
'eo', 'es', 'es-AR', 'es-CL', 'es-MX', 'et', 'eu', 'fa', 'ff', 'fi',
'fr', 'fy', 'fy-NL', 'ga', 'ga-IE', 'gd', 'gl', 'gu', 'gu-IN', 'he',
'hi-IN', 'hr', 'hsb', 'ht', 'hu', 'hy-AM', 'id', 'is', 'it', 'it-CH', 'ja',
'kk', 'km', 'kn', 'ko', 'ku', 'lij', 'lt', 'lv', 'mai', 'mk', 'ml',
'mr', 'ms', 'nb-NO', 'ne-NP', 'nl', 'nn-NO', 'or', 'pa', 'pa-IN',
'pl', 'pt', 'pt-BR', 'pt-PT', 'rm', 'ro', 'ru', 'si', 'sk', 'sl',
'son', 'sq', 'sr', 'sr-LATN', 'sv', 'sv-SE', 'ta', 'te', 'th', 'tr',
'uk', 'ur', 'vi', 'xh', 'zh-CN', 'zh-TW', 'zu'],
default: [
'af', 'an', 'ar', 'as', 'ast', 'be', 'bg', 'bn-BD', 'bn-IN', 'br',
'bs', 'ca', 'cs', 'cy', 'da', 'de', 'dsb', 'el', 'en-GB', 'en-US', 'en-ZA',
'eo', 'es', 'es-AR', 'es-CL', 'es-MX', 'et', 'eu', 'fa', 'ff', 'fi',
'fr', 'fy', 'fy-NL', 'ga', 'ga-IE', 'gd', 'gl', 'gu', 'gu-IN', 'he',
'hi-IN', 'hr', 'hsb', 'ht', 'hu', 'hy-AM', 'id', 'is', 'it', 'it-CH', 'ja',
'kk', 'km', 'kn', 'ko', 'ku', 'lij', 'lt', 'lv', 'mai', 'mk', 'ml',
'mr', 'ms', 'nb-NO', 'ne-NP', 'nl', 'nn-NO', 'or', 'pa', 'pa-IN',
'pl', 'pt', 'pt-BR', 'pt-PT', 'rm', 'ro', 'ru', 'si', 'sk', 'sl',
'son', 'sq', 'sr', 'sr-LATN', 'sv', 'sv-SE', 'ta', 'te', 'th', 'tr',
'uk', 'ur', 'vi', 'xh', 'zh-CN', 'zh-TW', 'zu'
],
env: 'I18N_SUPPORTED_LANGUAGES'
},
translationDirectory: {
@ -197,10 +199,12 @@ var conf = module.exports = convict({
unsupportedLanguages: {
doc: 'These languages should use system fonts instead of Fira Sans',
format: Array,
default: [ 'an', 'ar', 'as', 'ast', 'bn-DB', 'bn-IN', 'fa', 'ff', 'gd',
'gu', 'gu-IN', 'he', 'hi-IN', 'ht', 'hy-AM', 'ja', 'km', 'kn', 'ko', 'lij',
'mai', 'ml', 'mr', 'ne-NP', 'or', 'pa', 'pa-IN', 'si', 'son', 'ta', 'te',
'th', 'ur', 'vi', 'zh-CN', 'zh-TW' ]
default: [
'an', 'ar', 'as', 'ast', 'bn-DB', 'bn-IN', 'fa', 'ff', 'gd',
'gu', 'gu-IN', 'he', 'hi-IN', 'ht', 'hy-AM', 'ja', 'km', 'kn', 'ko', 'lij',
'mai', 'ml', 'mr', 'ne-NP', 'or', 'pa', 'pa-IN', 'si', 'son', 'ta', 'te',
'th', 'ur', 'vi', 'zh-CN', 'zh-TW'
]
}
}
},
@ -213,12 +217,12 @@ var conf = module.exports = convict({
}
},
key_path: {
doc: 'The location of the SSL key in pem format',
default: path.resolve(__dirname, '..', '..', 'key.pem')
doc: 'The location of the SSL key in pem format',
default: path.resolve(__dirname, '..', '..', 'key.pem')
},
cert_path: {
doc: 'The location of the SSL certificate in pem format',
default: path.resolve(__dirname, '..', '..', 'cert.pem')
doc: 'The location of the SSL certificate in pem format',
default: path.resolve(__dirname, '..', '..', 'cert.pem')
}
});

Просмотреть файл

@ -11,19 +11,19 @@ var helmet = require('helmet');
var config = require('./configuration');
var cspMiddleware = helmet.csp({
'default-src': ['\'self\''],
'connect-src': [
'\'self\'',
config.get('fxaccount_url'),
config.get('oauth_url')
],
'img-src': [
'\'self\'',
'data:',
'https://www.gravatar.com'
],
'report-uri': '/_/csp-violation'
});
'default-src': ['\'self\''],
'connect-src': [
'\'self\'',
config.get('fxaccount_url'),
config.get('oauth_url')
],
'img-src': [
'\'self\'',
'data:',
'https://www.gravatar.com'
],
'report-uri': '/_/csp-violation'
});
module.exports = function (req, res, next) {
if (! requiresCsp(req)) {

Просмотреть файл

@ -29,11 +29,11 @@ module.exports = function () {
return config.get('disable_route_logging')
? disabled
: expressLogger({
format: formats[config.get('route_log_format')],
stream: {
write: function (x) {
logger.info(typeof x === 'string' ? x.trim() : x);
}
format: formats[config.get('route_log_format')],
stream: {
write: function (x) {
logger.info(typeof x === 'string' ? x.trim() : x);
}
});
}
});
};

Просмотреть файл

@ -62,23 +62,23 @@ function getCommitHashFromGit() {
var l10nVersion = (function () {
var version;
try {
try {
var bowerPath = '../../../app/bower_components/fxa-content-server-l10n/.bower.json';
var bowerInfo = require(bowerPath);
version = bowerInfo && bowerInfo._release;
} catch(e) {
}
}
return version || 'unknown';
})();
var tosPpVersion = (function () {
var version;
try {
try {
var bowerPath = '../../../app/bower_components/tos-pp/.bower.json';
var bowerInfo = require(bowerPath);
version = bowerInfo && bowerInfo._release;
} catch(e) {
}
}
return version || 'unknown';
})();
@ -127,4 +127,3 @@ exports.process = function (req, res) {
res.json(versionInfo);
});
};

Просмотреть файл

@ -39,8 +39,8 @@ define([
var self = this;
return client.signUp(email, PASSWORD, { preVerified: true })
.then(function () {
return FunctionalHelpers.clearBrowserState(self);
})
return FunctionalHelpers.clearBrowserState(self);
})
.then(function () {
return self.get('remote')
.get(require.toUrl(SIGNIN_URL))

Просмотреть файл

@ -171,7 +171,7 @@ define([
.end()
.then(FunctionalHelpers.visibleByQSA('.success'))
.findByClassName('success').isDisplayed()
.then(function (isDisplayed) {
assert.equal(isDisplayed, true);

Просмотреть файл

@ -38,9 +38,9 @@ define([
var self = this;
return client.signUp(email, FIRST_PASSWORD, { preVerified: true })
.then(function () {
return FunctionalHelpers.clearBrowserState(self);
});
.then(function () {
return FunctionalHelpers.clearBrowserState(self);
});
},
teardown: function () {

Просмотреть файл

@ -6,11 +6,11 @@
// These default settings work OK for most people. The options that *must* be changed below are the
// packages, suites, excludeInstrumentation, and (if you want functional tests) functionalSuites.
define([
'intern/lib/args',
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/topic',
'./tools/firefox_profile'
],
function (args, topic, firefoxProfile) {
'intern/lib/args',
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/topic',
'./tools/firefox_profile'
],
function (args, topic, firefoxProfile) {
'use strict';
var fxaAuthRoot = args.fxaAuthRoot || 'http://127.0.0.1:9000/v1';

Просмотреть файл

@ -51,19 +51,19 @@ define([
var dfd = this.async(1000);
request(serverUrl + '/template' + name, dfd.callback(function(err, res, body) {
var json = JSON.parse(body);
var json = JSON.parse(body);
assert.match(json.subject, matches.subject);
assert.match(json.text, matches.text);
assert.match(json.html, matches.html);
assert.match(json.subject, matches.subject);
assert.match(json.text, matches.text);
assert.match(json.html, matches.html);
// make sure these variables are present and use {{
assert.match(json.text, /{{{link}}}/);
assert.match(json.html, /[^{]{{link}}/);
assert.match(json.text, /{{{email}}}/);
assert.match(json.html, /[^{]{{email}}/);
// make sure these variables are present and use {{
assert.match(json.text, /{{{link}}}/);
assert.match(json.html, /[^{]{{link}}/);
assert.match(json.text, /{{{email}}}/);
assert.match(json.html, /[^{]{{email}}/);
}, dfd.reject.bind(dfd)));
}, dfd.reject.bind(dfd)));
};
}

Просмотреть файл

@ -3,36 +3,35 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
define([
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!path',
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!execSync'
],
function (path, execSync) {
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!path',
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!execSync'
],
function (path, execSync) {
'use strict';
'use strict';
var createProfile = function(config) {
var profileProcess = null;
var encodedProfile = '';
var createProfile = function(config) {
var profileProcess = null;
var encodedProfile = '';
if (path) {
console.log('Creating Firefox profile...');
var profileArgs = JSON.stringify(JSON.stringify(config));
var profileTool = path.join('tests', 'tools', 'firefox_profile_creator.js');
try {
profileProcess = execSync.exec(['node', profileTool, profileArgs].join(' '));
} catch (e) {
console.log('Note: execSync failed to run:', e);
}
if (profileProcess && profileProcess.code === 0) {
encodedProfile = profileProcess.stdout;
} else {
console.log('Note: Failed to generate a Firefox profile for this configuration.');
}
return encodedProfile;
if (path) {
console.log('Creating Firefox profile...');
var profileArgs = JSON.stringify(JSON.stringify(config));
var profileTool = path.join('tests', 'tools', 'firefox_profile_creator.js');
try {
profileProcess = execSync.exec(['node', profileTool, profileArgs].join(' '));
} catch (e) {
console.log('Note: execSync failed to run:', e);
}
};
return createProfile;
if (profileProcess && profileProcess.code === 0) {
encodedProfile = profileProcess.stdout;
} else {
console.log('Note: Failed to generate a Firefox profile for this configuration.');
}
return encodedProfile;
}
};
return createProfile;
});