diff --git a/app/api/server/v1/misc.js b/app/api/server/v1/misc.js index aff12d110df7a..3b275a78d6300 100644 --- a/app/api/server/v1/misc.js +++ b/app/api/server/v1/misc.js @@ -49,8 +49,16 @@ API.v1.addRoute('info', { authRequired: false }, { API.v1.addRoute('me', { authRequired: true }, { get() { - const { 'services.password.bcrypt': password, ...fields } = getDefaultUserFields(); - return API.v1.success(this.getUserInfo(Users.findOneById(this.userId, { fields }))); + const fields = getDefaultUserFields(); + const user = Users.findOneById(this.userId, { fields }); + + // The password hash shouldn't be leaked but the client may need to know if it exists. + if (user?.services?.password?.bcrypt) { + user.services.password.exists = true; + delete user.services.password.bcrypt; + } + + return API.v1.success(this.getUserInfo(user)); }, }); diff --git a/client/views/account/AccountProfilePage.js b/client/views/account/AccountProfilePage.js index 5c3b83f209a2e..e6bae83c4afd3 100644 --- a/client/views/account/AccountProfilePage.js +++ b/client/views/account/AccountProfilePage.js @@ -48,7 +48,7 @@ const AccountProfilePage = () => { const closeModal = useCallback(() => setModal(null), [setModal]); - const localPassword = Boolean(user?.services?.password?.bcrypt?.trim()); + const localPassword = Boolean(user?.services?.password?.exists); const erasureType = useSetting('Message_ErasureType'); const allowRealNameChange = useSetting('Accounts_AllowRealNameChange'); @@ -67,7 +67,7 @@ const AccountProfilePage = () => { const namesRegexSetting = useSetting('UTF8_Names_Validation'); if (allowPasswordChange && !allowOAuthPasswordChange) { - allowPasswordChange = Boolean(user?.services?.password?.bcrypt); + allowPasswordChange = localPassword; } const namesRegex = useMemo(() => new RegExp(`^${namesRegexSetting}$`), [namesRegexSetting]); diff --git a/tests/end-to-end/api/00-miscellaneous.js b/tests/end-to-end/api/00-miscellaneous.js index 6a4c0ae4e9a1f..5dab1b75bd52d 100644 --- a/tests/end-to-end/api/00-miscellaneous.js +++ b/tests/end-to-end/api/00-miscellaneous.js @@ -156,7 +156,7 @@ describe('miscellaneous', function() { expect(res.body).to.have.nested.property('emails[0].address', adminEmail); expect(res.body).to.have.nested.property('settings.preferences').and.to.be.an('object'); expect(res.body.settings.preferences).to.have.all.keys(allUserPreferencesKeys); - expect(res.body.services).to.not.have.property('password'); + expect(res.body.services).to.not.have.nested.property('password.bcrypt'); }) .end(done); });