diff --git a/logic/auth.js b/logic/auth.js index a5758a3..ebd2dbb 100644 --- a/logic/auth.js +++ b/logic/auth.js @@ -15,14 +15,20 @@ const saltRounds = 10; const SYSTEM_USER = UUID.fetchBootUUID() || 'admin'; let devicePassword = ''; +let changeNameStatus; let changePasswordStatus; +resetChangeNameStatus(); resetChangePasswordStatus(); function resetChangePasswordStatus() { changePasswordStatus = { percent: 0 }; } +function resetChangeNameStatus() { + changeNameStatus = { percent: 0 }; +} + async function sleepSeconds(seconds) { return new Promise(resolve => { setTimeout(resolve, seconds * constants.TIME.ONE_SECOND_IN_MILLIS); @@ -39,6 +45,34 @@ function getCachedPassword() { return devicePassword; } +// Change the device name +async function changeName(name) { + resetChangeNameStatus(); + + changeNameStatus.percent = 1; // eslint-disable-line no-magic-numbers + + changeNameStatus.percent = 30; // eslint-disable-line no-magic-numbers + + try { + // get user data + const user = await diskLogic.readUserFile(); + changeNameStatus.percent = 60; // eslint-disable-line no-magic-numbers + + // update user name + user.name = name; + + // update user file + await diskLogic.writeUserFile({ ...user }); + + changeNameStatus.percent = 100; + } catch (error) { + changeNameStatus.error = true; + changeNameStatus.percent = 100; + + throw error; + } +} + // Sets system password const setSystemPassword = async password => { await diskLogic.writeStatusFile('password', password); @@ -78,6 +112,10 @@ async function changePassword(currentPassword, newPassword, jwt) { } } +function getChangeNameStatus() { + return changeNameStatus; +} + function getChangePasswordStatus() { return changePasswordStatus; } @@ -257,8 +295,10 @@ async function refresh(user) { module.exports = { + changeName, changePassword, getCachedPassword, + getChangeNameStatus, getChangePasswordStatus, hashCredentials, isRegistered, diff --git a/routes/v1/account.js b/routes/v1/account.js index d975b41..9672cde 100644 --- a/routes/v1/account.js +++ b/routes/v1/account.js @@ -13,6 +13,31 @@ const validator = require('utils/validator.js'); const COMPLETE = 100; +router.post('/change-name', auth.jwt, safeHandler(async (req, res, next) => { + const newName = req.body.newName; + + try { + validator.isString(newName); + } catch (error) { + return next(error); + } + + const status = await authLogic.getChangeNameStatus(); + + // return a conflict if a change name process is already running + if (status.percent > 0 && status.percent !== COMPLETE) { + return res.status(constants.STATUS_CODES.CONFLICT).json(); + } + + try { + // start change name process in the background and immediately return + await authLogic.changeName(newName); + return res.status(constants.STATUS_CODES.OK).json(); + } catch (error) { + return next(error); + } +})); + // Endpoint to change your password. router.post('/change-password', auth.convertReqBodyToBasicAuth, auth.basic, incorrectPasswordAuthHandler, safeHandler(async (req, res, next) => { // Use password from the body by default. Basic auth has issues handling special characters.