profile: store preferred language in the database

This commit is contained in:
Girish Ramakrishnan
2024-02-26 12:32:14 +01:00
parent 6d6107161e
commit 6525504923
10 changed files with 150 additions and 14 deletions

View File

@@ -72,7 +72,7 @@ exports = module.exports = {
const ORDERED_ROLES = [ exports.ROLE_USER, exports.ROLE_USER_MANAGER, exports.ROLE_MAIL_MANAGER, exports.ROLE_ADMIN, exports.ROLE_OWNER ];
// the avatar and backgroundImage fields are special and not added here to reduce response sizes
const USERS_FIELDS = [ 'id', 'username', 'email', 'fallbackEmail', 'password', 'salt', 'creationTime', 'inviteToken', 'resetToken', 'displayName',
const USERS_FIELDS = [ 'id', 'username', 'email', 'fallbackEmail', 'password', 'salt', 'creationTime', 'inviteToken', 'resetToken', 'displayName', 'language',
'twoFactorAuthenticationEnabled', 'twoFactorAuthenticationSecret', 'active', 'source', 'role', 'resetTokenCreationTime', 'loginLocationsJson' ].join(',');
const DEFAULT_GHOST_LIFETIME = 6 * 60 * 60 * 1000; // 6 hours
@@ -96,6 +96,7 @@ const appPasswords = require('./apppasswords.js'),
settings = require('./settings.js'),
speakeasy = require('speakeasy'),
tokens = require('./tokens.js'),
translation = require('./translation.js'),
uuid = require('uuid'),
uaParser = require('ua-parser-js'),
superagent = require('superagent'),
@@ -164,6 +165,17 @@ function validateDisplayName(name) {
return null;
}
async function validateLanguage(language) {
assert.strictEqual(typeof language, 'string');
if (language === '') return null; // reset to platform default
const languages = await translation.listLanguages();
if (!languages.includes(language)) return new BoxError(BoxError.BAD_FIELD, 'Invalid language');
return null;
}
function validatePassword(password) {
assert.strictEqual(typeof password, 'string');
@@ -249,11 +261,12 @@ async function add(email, data, auditSource) {
displayName: displayName,
source: source,
role: role,
avatar: constants.AVATAR_NONE
avatar: constants.AVATAR_NONE,
language: ''
};
const query = 'INSERT INTO users (id, username, password, email, fallbackEmail, salt, resetToken, inviteToken, displayName, source, role, avatar) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
const args = [ user.id, user.username, user.password, user.email, user.fallbackEmail, user.salt, user.resetToken, user.inviteToken, user.displayName, user.source, user.role, user.avatar ];
const query = 'INSERT INTO users (id, username, password, email, fallbackEmail, salt, resetToken, inviteToken, displayName, source, role, avatar, language) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
const args = [ user.id, user.username, user.password, user.email, user.fallbackEmail, user.salt, user.resetToken, user.inviteToken, user.displayName, user.source, user.role, user.avatar, user.language ];
[error] = await safe(database.query(query, args));
if (error && error.code === 'ER_DUP_ENTRY' && error.sqlMessage.indexOf('users_email') !== -1) throw new BoxError(BoxError.ALREADY_EXISTS, 'email already exists');
@@ -608,8 +621,13 @@ async function update(user, data, auditSource) {
if (error) throw error;
}
let args = [ ];
let fields = [ ];
if (data.language) {
error = await validateLanguage(data.language);
if (error) throw error;
}
let args = [];
let fields = [];
for (const k in data) {
if (k === 'twoFactorAuthenticationEnabled' || k === 'active') {
fields.push(k + ' = ?');