HaikuDepot: Password Requirements
Obtains HDS's password requirements and displays those to the user when creating a new account. Relates to #13986 Change-Id: I1b76181e17bc03e9baf915dadcd3c45f9eb89b3f Reviewed-on: https://review.haiku-os.org/c/haiku/+/6203 Tested-by: Automation <[email protected]> Reviewed-by: Jérôme Duval <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
@@ -140,6 +140,7 @@ local applicationSources =
|
|||||||
PackageInfoListener.cpp
|
PackageInfoListener.cpp
|
||||||
PackageInfoView.cpp
|
PackageInfoView.cpp
|
||||||
PackageListView.cpp
|
PackageListView.cpp
|
||||||
|
PasswordRequirements.cpp
|
||||||
RatePackageWindow.cpp
|
RatePackageWindow.cpp
|
||||||
RatingView.cpp
|
RatingView.cpp
|
||||||
RatingStability.cpp
|
RatingStability.cpp
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Andrew Lindesay <[email protected]>.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PasswordRequirements.h"
|
||||||
|
|
||||||
|
// These are keys that are used to store this object's data into a BMessage
|
||||||
|
// instance.
|
||||||
|
|
||||||
|
#define KEY_MIN_PASSWORD_LENGTH "minPasswordLength"
|
||||||
|
#define KEY_MIN_PASSWORD_UPPERCASE_CHAR "minPasswordUppercaseChar"
|
||||||
|
#define KEY_MIN_PASSWORD_DIGITS_CHAR "minPasswordDigitsChar"
|
||||||
|
|
||||||
|
|
||||||
|
PasswordRequirements::PasswordRequirements()
|
||||||
|
:
|
||||||
|
fMinPasswordLength(0),
|
||||||
|
fMinPasswordUppercaseChar(0),
|
||||||
|
fMinPasswordDigitsChar(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PasswordRequirements::PasswordRequirements(BMessage* from)
|
||||||
|
:
|
||||||
|
fMinPasswordLength(0),
|
||||||
|
fMinPasswordUppercaseChar(0),
|
||||||
|
fMinPasswordDigitsChar(0)
|
||||||
|
{
|
||||||
|
uint32 value;
|
||||||
|
|
||||||
|
if (from->FindUInt32(KEY_MIN_PASSWORD_LENGTH, &value) == B_OK) {
|
||||||
|
fMinPasswordLength = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from->FindUInt32(
|
||||||
|
KEY_MIN_PASSWORD_UPPERCASE_CHAR, &value) == B_OK) {
|
||||||
|
fMinPasswordUppercaseChar = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from->FindUInt32(
|
||||||
|
KEY_MIN_PASSWORD_DIGITS_CHAR, &value) == B_OK) {
|
||||||
|
fMinPasswordDigitsChar = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PasswordRequirements::~PasswordRequirements()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PasswordRequirements::SetMinPasswordLength(uint32 value)
|
||||||
|
{
|
||||||
|
fMinPasswordLength = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PasswordRequirements::SetMinPasswordUppercaseChar(uint32 value)
|
||||||
|
{
|
||||||
|
fMinPasswordUppercaseChar = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PasswordRequirements::SetMinPasswordDigitsChar(uint32 value)
|
||||||
|
{
|
||||||
|
fMinPasswordDigitsChar = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PasswordRequirements::Archive(BMessage* into, bool deep) const
|
||||||
|
{
|
||||||
|
status_t result = B_OK;
|
||||||
|
if (result == B_OK) {
|
||||||
|
result = into->AddUInt32(
|
||||||
|
KEY_MIN_PASSWORD_LENGTH, fMinPasswordLength);
|
||||||
|
}
|
||||||
|
if (result == B_OK) {
|
||||||
|
result = into->AddUInt32(
|
||||||
|
KEY_MIN_PASSWORD_UPPERCASE_CHAR, fMinPasswordUppercaseChar);
|
||||||
|
}
|
||||||
|
if (result == B_OK) {
|
||||||
|
result = into->AddUInt32(
|
||||||
|
KEY_MIN_PASSWORD_DIGITS_CHAR, fMinPasswordDigitsChar);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023, Andrew Lindesay <[email protected]>.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef PASSWORD_REQUIREMENTS_H
|
||||||
|
#define PASSWORD_REQUIREMENTS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Archivable.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*! When a user enters their password there are requirements around that
|
||||||
|
password such as the length of the password in characters as well as
|
||||||
|
how many digits it must contain. This class models those
|
||||||
|
requirements so that they can be conveyed to the user in the UI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PasswordRequirements : public BArchivable {
|
||||||
|
public:
|
||||||
|
PasswordRequirements(BMessage* from);
|
||||||
|
PasswordRequirements();
|
||||||
|
virtual ~PasswordRequirements();
|
||||||
|
|
||||||
|
const uint32 MinPasswordLength() const
|
||||||
|
{ return fMinPasswordLength; }
|
||||||
|
const uint32 MinPasswordUppercaseChar() const
|
||||||
|
{ return fMinPasswordUppercaseChar; }
|
||||||
|
const uint32 MinPasswordDigitsChar() const
|
||||||
|
{ return fMinPasswordDigitsChar; }
|
||||||
|
|
||||||
|
void SetMinPasswordLength(uint32 value);
|
||||||
|
void SetMinPasswordUppercaseChar(uint32 value);
|
||||||
|
void SetMinPasswordDigitsChar(uint32 value);
|
||||||
|
|
||||||
|
status_t Archive(BMessage* into, bool deep = true) const;
|
||||||
|
private:
|
||||||
|
uint32 fMinPasswordLength;
|
||||||
|
uint32 fMinPasswordUppercaseChar;
|
||||||
|
uint32 fMinPasswordDigitsChar;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PASSWORD_REQUIREMENTS_H
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014, Stephan Aßmus <[email protected]>.
|
* Copyright 2014, Stephan Aßmus <[email protected]>.
|
||||||
* Copyright 2016-2022, Andrew Lindesay <[email protected]>.
|
* Copyright 2016-2023, Andrew Lindesay <[email protected]>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -741,6 +741,57 @@ WebAppInterface::IncrementViewCounter(const PackageInfoRef package,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
WebAppInterface::RetrievePasswordRequirements(
|
||||||
|
PasswordRequirements& passwordRequirements)
|
||||||
|
{
|
||||||
|
BMessage responseEnvelopeMessage;
|
||||||
|
status_t result = _RetrievePasswordRequirementsMeta(
|
||||||
|
responseEnvelopeMessage);
|
||||||
|
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
BMessage resultMessage;
|
||||||
|
|
||||||
|
result = responseEnvelopeMessage.FindMessage("result", &resultMessage);
|
||||||
|
|
||||||
|
if (result != B_OK) {
|
||||||
|
HDERROR("bad response envelope missing 'result' entry");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value;
|
||||||
|
|
||||||
|
if (resultMessage.FindDouble("minPasswordLength", &value) == B_OK)
|
||||||
|
passwordRequirements.SetMinPasswordLength((uint32) value);
|
||||||
|
|
||||||
|
if (resultMessage.FindDouble("minPasswordUppercaseChar", &value) == B_OK)
|
||||||
|
passwordRequirements.SetMinPasswordUppercaseChar((uint32) value);
|
||||||
|
|
||||||
|
if (resultMessage.FindDouble("minPasswordDigitsChar", &value) == B_OK)
|
||||||
|
passwordRequirements.SetMinPasswordDigitsChar((uint32) value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
WebAppInterface::_RetrievePasswordRequirementsMeta(BMessage& message)
|
||||||
|
{
|
||||||
|
BMallocIO* requestEnvelopeData = new BMallocIO();
|
||||||
|
// BHttpRequest later takes ownership of this.
|
||||||
|
BJsonTextWriter requestEnvelopeWriter(requestEnvelopeData);
|
||||||
|
|
||||||
|
requestEnvelopeWriter.WriteObjectStart();
|
||||||
|
requestEnvelopeWriter.WriteObjectEnd();
|
||||||
|
|
||||||
|
return _SendJsonRequest("user/get-password-requirements",
|
||||||
|
requestEnvelopeData, _LengthAndSeekToZero(requestEnvelopeData),
|
||||||
|
0, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! JSON-RPC invocations return a response. The response may be either
|
/*! JSON-RPC invocations return a response. The response may be either
|
||||||
a result or it may be an error depending on the response structure.
|
a result or it may be an error depending on the response structure.
|
||||||
If it is an error then there may be additional detail that is the
|
If it is an error then there may be additional detail that is the
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014, Stephan Aßmus <[email protected]>.
|
* Copyright 2014, Stephan Aßmus <[email protected]>.
|
||||||
* Copyright 2016-2022, Andrew Lindesay <[email protected]>.
|
* Copyright 2016-2023, Andrew Lindesay <[email protected]>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef WEB_APP_INTERFACE_H
|
#ifndef WEB_APP_INTERFACE_H
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <package/PackageVersion.h>
|
#include <package/PackageVersion.h>
|
||||||
|
|
||||||
#include "PackageInfo.h"
|
#include "PackageInfo.h"
|
||||||
|
#include "PasswordRequirements.h"
|
||||||
#include "UserCredentials.h"
|
#include "UserCredentials.h"
|
||||||
#include "UserDetail.h"
|
#include "UserDetail.h"
|
||||||
#include "UserUsageConditions.h"
|
#include "UserUsageConditions.h"
|
||||||
@@ -129,6 +130,9 @@ public:
|
|||||||
const DepotInfoRef depot,
|
const DepotInfoRef depot,
|
||||||
BMessage& message);
|
BMessage& message);
|
||||||
|
|
||||||
|
status_t RetrievePasswordRequirements(
|
||||||
|
PasswordRequirements& passwordRequirements);
|
||||||
|
|
||||||
static int32 ErrorCodeFromResponse(
|
static int32 ErrorCodeFromResponse(
|
||||||
BMessage& responseEnvelopeMessage);
|
BMessage& responseEnvelopeMessage);
|
||||||
|
|
||||||
@@ -137,6 +141,8 @@ public:
|
|||||||
UserDetail& userDetail);
|
UserDetail& userDetail);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
status_t _RetrievePasswordRequirementsMeta(
|
||||||
|
BMessage& message);
|
||||||
|
|
||||||
status_t _RetrieveUserUsageConditionsMeta(
|
status_t _RetrieveUserUsageConditionsMeta(
|
||||||
const BString& code, BMessage& message);
|
const BString& code, BMessage& message);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014, Stephan Aßmus <[email protected]>.
|
* Copyright 2014, Stephan Aßmus <[email protected]>.
|
||||||
* Copyright 2019-2021, Andrew Lindesay <[email protected]>.
|
* Copyright 2019-2023, Andrew Lindesay <[email protected]>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
#define KEY_USER_CREDENTIALS "userCredentials"
|
#define KEY_USER_CREDENTIALS "userCredentials"
|
||||||
#define KEY_CAPTCHA_IMAGE "captchaImage"
|
#define KEY_CAPTCHA_IMAGE "captchaImage"
|
||||||
#define KEY_USER_USAGE_CONDITIONS "userUsageConditions"
|
#define KEY_USER_USAGE_CONDITIONS "userUsageConditions"
|
||||||
|
#define KEY_PASSWORD_REQUIREMENTS "passwordRequirements"
|
||||||
#define KEY_VALIDATION_FAILURES "validationFailures"
|
#define KEY_VALIDATION_FAILURES "validationFailures"
|
||||||
|
|
||||||
|
|
||||||
@@ -67,7 +68,8 @@ enum {
|
|||||||
MSG_LOGIN_ERROR = 'lter',
|
MSG_LOGIN_ERROR = 'lter',
|
||||||
MSG_CREATE_ACCOUNT_SUCCESS = 'csuc',
|
MSG_CREATE_ACCOUNT_SUCCESS = 'csuc',
|
||||||
MSG_CREATE_ACCOUNT_FAILED = 'cfai',
|
MSG_CREATE_ACCOUNT_FAILED = 'cfai',
|
||||||
MSG_CREATE_ACCOUNT_ERROR = 'cfae'
|
MSG_CREATE_ACCOUNT_ERROR = 'cfae',
|
||||||
|
MSG_VIEW_PASSWORD_REQUIREMENTS = 'vpar'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -78,7 +80,8 @@ enum {
|
|||||||
|
|
||||||
enum CreateAccountSetupMask {
|
enum CreateAccountSetupMask {
|
||||||
CREATE_CAPTCHA = 1 << 1,
|
CREATE_CAPTCHA = 1 << 1,
|
||||||
FETCH_USER_USAGE_CONDITIONS = 1 << 2
|
FETCH_USER_USAGE_CONDITIONS = 1 << 2,
|
||||||
|
FETCH_PASSWORD_REQUIREMENTS = 1 << 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -121,6 +124,7 @@ UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame, Model& model)
|
|||||||
B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL,
|
B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL,
|
||||||
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS
|
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS
|
||||||
| B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE),
|
| B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE),
|
||||||
|
fPasswordRequirements(NULL),
|
||||||
fUserUsageConditions(NULL),
|
fUserUsageConditions(NULL),
|
||||||
fCaptcha(NULL),
|
fCaptcha(NULL),
|
||||||
fPreferredLanguageCode(LANGUAGE_DEFAULT_CODE),
|
fPreferredLanguageCode(LANGUAGE_DEFAULT_CODE),
|
||||||
@@ -178,6 +182,10 @@ UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame, Model& model)
|
|||||||
B_TRANSLATE("View the usage conditions"),
|
B_TRANSLATE("View the usage conditions"),
|
||||||
new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS));
|
new BMessage(MSG_VIEW_LATEST_USER_USAGE_CONDITIONS));
|
||||||
fUserUsageConditionsLink->SetTarget(this);
|
fUserUsageConditionsLink->SetTarget(this);
|
||||||
|
fPasswordRequirementsLink = new LinkView("password requirements view",
|
||||||
|
B_TRANSLATE("View the password requirements"),
|
||||||
|
new BMessage(MSG_VIEW_PASSWORD_REQUIREMENTS));
|
||||||
|
fPasswordRequirementsLink->SetTarget(this);
|
||||||
|
|
||||||
// Setup modification messages on all text fields to trigger validation
|
// Setup modification messages on all text fields to trigger validation
|
||||||
// of input
|
// of input
|
||||||
@@ -208,14 +216,15 @@ UserLoginWindow::UserLoginWindow(BWindow* parent, BRect frame, Model& model)
|
|||||||
BLayoutBuilder::Grid<>(createAccountCard)
|
BLayoutBuilder::Grid<>(createAccountCard)
|
||||||
.AddTextControl(fNewNicknameField, 0, 0)
|
.AddTextControl(fNewNicknameField, 0, 0)
|
||||||
.AddTextControl(fNewPasswordField, 0, 1)
|
.AddTextControl(fNewPasswordField, 0, 1)
|
||||||
.AddTextControl(fRepeatPasswordField, 0, 2)
|
.Add(fPasswordRequirementsLink, 1, 2)
|
||||||
.AddTextControl(fEmailField, 0, 3)
|
.AddTextControl(fRepeatPasswordField, 0, 3)
|
||||||
.AddMenuField(fLanguageCodeField, 0, 4)
|
.AddTextControl(fEmailField, 0, 4)
|
||||||
.Add(fCaptchaView, 0, 5)
|
.AddMenuField(fLanguageCodeField, 0, 5)
|
||||||
.Add(fCaptchaResultField, 1, 5)
|
.Add(fCaptchaView, 0, 6)
|
||||||
.Add(fConfirmMinimumAgeCheckBox, 1, 6)
|
.Add(fCaptchaResultField, 1, 6)
|
||||||
.Add(fConfirmUserUsageConditionsCheckBox, 1, 7)
|
.Add(fConfirmMinimumAgeCheckBox, 1, 7)
|
||||||
.Add(fUserUsageConditionsLink, 1, 8)
|
.Add(fConfirmUserUsageConditionsCheckBox, 1, 8)
|
||||||
|
.Add(fUserUsageConditionsLink, 1, 9)
|
||||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||||
;
|
;
|
||||||
fTabView->AddTab(createAccountCard);
|
fTabView->AddTab(createAccountCard);
|
||||||
@@ -265,6 +274,10 @@ UserLoginWindow::MessageReceived(BMessage* message)
|
|||||||
_ViewUserUsageConditions();
|
_ViewUserUsageConditions();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_VIEW_PASSWORD_REQUIREMENTS:
|
||||||
|
_ViewPasswordRequirements();
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_SEND:
|
case MSG_SEND:
|
||||||
switch (fMode) {
|
switch (fMode) {
|
||||||
case LOGIN:
|
case LOGIN:
|
||||||
@@ -401,6 +414,7 @@ UserLoginWindow::_EnableMutableControls(bool enabled)
|
|||||||
fConfirmMinimumAgeCheckBox->SetEnabled(enabled);
|
fConfirmMinimumAgeCheckBox->SetEnabled(enabled);
|
||||||
fConfirmUserUsageConditionsCheckBox->SetEnabled(enabled);
|
fConfirmUserUsageConditionsCheckBox->SetEnabled(enabled);
|
||||||
fUserUsageConditionsLink->SetEnabled(enabled);
|
fUserUsageConditionsLink->SetEnabled(enabled);
|
||||||
|
fPasswordRequirementsLink->SetEnabled(enabled);
|
||||||
fSendButton->SetEnabled(enabled);
|
fSendButton->SetEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,6 +681,8 @@ UserLoginWindow::_CreateAccountSetupIfNecessary()
|
|||||||
setupMask |= CREATE_CAPTCHA;
|
setupMask |= CREATE_CAPTCHA;
|
||||||
if (fUserUsageConditions == NULL)
|
if (fUserUsageConditions == NULL)
|
||||||
setupMask |= FETCH_USER_USAGE_CONDITIONS;
|
setupMask |= FETCH_USER_USAGE_CONDITIONS;
|
||||||
|
if (fPasswordRequirements == NULL)
|
||||||
|
setupMask |= FETCH_PASSWORD_REQUIREMENTS;
|
||||||
_CreateAccountSetup(setupMask);
|
_CreateAccountSetup(setupMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -695,6 +711,8 @@ UserLoginWindow::_CreateAccountSetup(uint32 mask)
|
|||||||
_SetCaptcha(NULL);
|
_SetCaptcha(NULL);
|
||||||
if ((mask & FETCH_USER_USAGE_CONDITIONS) != 0)
|
if ((mask & FETCH_USER_USAGE_CONDITIONS) != 0)
|
||||||
_SetUserUsageConditions(NULL);
|
_SetUserUsageConditions(NULL);
|
||||||
|
if ((mask & FETCH_PASSWORD_REQUIREMENTS) != 0)
|
||||||
|
_SetPasswordRequirements(NULL);
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
@@ -722,9 +740,13 @@ UserLoginWindow::_CreateAccountSetupThreadEntry(void* data)
|
|||||||
status_t result = B_OK;
|
status_t result = B_OK;
|
||||||
Captcha captcha;
|
Captcha captcha;
|
||||||
UserUsageConditions userUsageConditions;
|
UserUsageConditions userUsageConditions;
|
||||||
|
PasswordRequirements passwordRequirements;
|
||||||
|
|
||||||
bool shouldCreateCaptcha = (threadData->mask & CREATE_CAPTCHA) != 0;
|
bool shouldCreateCaptcha = (threadData->mask & CREATE_CAPTCHA) != 0;
|
||||||
bool shouldFetchUserUsageConditions
|
bool shouldFetchUserUsageConditions
|
||||||
= (threadData->mask & FETCH_USER_USAGE_CONDITIONS) != 0;
|
= (threadData->mask & FETCH_USER_USAGE_CONDITIONS) != 0;
|
||||||
|
bool shouldFetchPasswordRequirements
|
||||||
|
= (threadData->mask & FETCH_PASSWORD_REQUIREMENTS) != 0;
|
||||||
|
|
||||||
if (result == B_OK && shouldCreateCaptcha)
|
if (result == B_OK && shouldCreateCaptcha)
|
||||||
result = threadData->window->_CreateAccountCaptchaSetupThread(captcha);
|
result = threadData->window->_CreateAccountCaptchaSetupThread(captcha);
|
||||||
@@ -732,6 +754,16 @@ UserLoginWindow::_CreateAccountSetupThreadEntry(void* data)
|
|||||||
result = threadData->window
|
result = threadData->window
|
||||||
->_CreateAccountUserUsageConditionsSetupThread(userUsageConditions);
|
->_CreateAccountUserUsageConditionsSetupThread(userUsageConditions);
|
||||||
}
|
}
|
||||||
|
if (result == B_OK && shouldFetchPasswordRequirements) {
|
||||||
|
result = threadData->window
|
||||||
|
->_CreateAccountPasswordRequirementsSetupThread(
|
||||||
|
passwordRequirements);
|
||||||
|
HDINFO("password requirements fetched; len %" B_PRId32
|
||||||
|
", caps %" B_PRId32 ", digits %" B_PRId32,
|
||||||
|
passwordRequirements.MinPasswordLength(),
|
||||||
|
passwordRequirements.MinPasswordUppercaseChar(),
|
||||||
|
passwordRequirements.MinPasswordUppercaseChar());
|
||||||
|
}
|
||||||
|
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
BMessage message(MSG_CREATE_ACCOUNT_SETUP_SUCCESS);
|
BMessage message(MSG_CREATE_ACCOUNT_SETUP_SUCCESS);
|
||||||
@@ -749,6 +781,14 @@ UserLoginWindow::_CreateAccountSetupThreadEntry(void* data)
|
|||||||
&userUsageConditionsMessage);
|
&userUsageConditionsMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result == B_OK && shouldFetchPasswordRequirements) {
|
||||||
|
BMessage passwordRequirementsMessage;
|
||||||
|
result = passwordRequirements.Archive(&passwordRequirementsMessage);
|
||||||
|
if (result == B_OK) {
|
||||||
|
result = message.AddMessage(KEY_PASSWORD_REQUIREMENTS,
|
||||||
|
&passwordRequirementsMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
HDDEBUG("successfully completed collection of create account "
|
HDDEBUG("successfully completed collection of create account "
|
||||||
"data from the server in background thread");
|
"data from the server in background thread");
|
||||||
@@ -792,6 +832,27 @@ UserLoginWindow::_CreateAccountUserUsageConditionsSetupThread(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UserLoginWindow::_CreateAccountPasswordRequirementsSetupThread(
|
||||||
|
PasswordRequirements& passwordRequirements)
|
||||||
|
{
|
||||||
|
WebAppInterface interface = fModel.GetWebAppInterface();
|
||||||
|
status_t result = interface.RetrievePasswordRequirements(
|
||||||
|
passwordRequirements);
|
||||||
|
|
||||||
|
if (result != B_OK) {
|
||||||
|
AppUtils::NotifySimpleError(
|
||||||
|
B_TRANSLATE("Password requirements download problem"),
|
||||||
|
B_TRANSLATE("An error has arisen downloading the password "
|
||||||
|
"requirements required to create a new user. Check the log for "
|
||||||
|
"details and try again. "
|
||||||
|
ALERT_MSG_LOGS_USER_GUIDE));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UserLoginWindow::_CreateAccountCaptchaSetupThread(Captcha& captcha)
|
UserLoginWindow::_CreateAccountCaptchaSetupThread(Captcha& captcha)
|
||||||
{
|
{
|
||||||
@@ -891,8 +952,10 @@ void
|
|||||||
UserLoginWindow::_HandleCreateAccountSetupSuccess(BMessage* message)
|
UserLoginWindow::_HandleCreateAccountSetupSuccess(BMessage* message)
|
||||||
{
|
{
|
||||||
HDDEBUG("handling account setup success");
|
HDDEBUG("handling account setup success");
|
||||||
|
|
||||||
BMessage captchaMessage;
|
BMessage captchaMessage;
|
||||||
BMessage userUsageConditionsMessage;
|
BMessage userUsageConditionsMessage;
|
||||||
|
BMessage passwordRequirementsMessage;
|
||||||
|
|
||||||
if (message->FindMessage(KEY_CAPTCHA_IMAGE, &captchaMessage) == B_OK)
|
if (message->FindMessage(KEY_CAPTCHA_IMAGE, &captchaMessage) == B_OK)
|
||||||
_SetCaptcha(new Captcha(&captchaMessage));
|
_SetCaptcha(new Captcha(&captchaMessage));
|
||||||
@@ -903,6 +966,12 @@ UserLoginWindow::_HandleCreateAccountSetupSuccess(BMessage* message)
|
|||||||
new UserUsageConditions(&userUsageConditionsMessage));
|
new UserUsageConditions(&userUsageConditionsMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message->FindMessage(KEY_PASSWORD_REQUIREMENTS,
|
||||||
|
&passwordRequirementsMessage) == B_OK) {
|
||||||
|
_SetPasswordRequirements(
|
||||||
|
new PasswordRequirements(&passwordRequirementsMessage));
|
||||||
|
}
|
||||||
|
|
||||||
_EnableMutableControls(true);
|
_EnableMutableControls(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,6 +1022,24 @@ UserLoginWindow::_SetUserUsageConditions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
UserLoginWindow::_SetPasswordRequirements(
|
||||||
|
PasswordRequirements* passwordRequirements)
|
||||||
|
{
|
||||||
|
HDDEBUG("setting password requirements");
|
||||||
|
if (fPasswordRequirements != NULL)
|
||||||
|
delete fPasswordRequirements;
|
||||||
|
fPasswordRequirements = passwordRequirements;
|
||||||
|
if (fPasswordRequirements != NULL) {
|
||||||
|
HDDEBUG("password requirements set to; len %" B_PRId32
|
||||||
|
", caps %" B_PRId32 ", digits %" B_PRId32,
|
||||||
|
fPasswordRequirements->MinPasswordLength(),
|
||||||
|
fPasswordRequirements->MinPasswordUppercaseChar(),
|
||||||
|
fPasswordRequirements->MinPasswordUppercaseChar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Create Account
|
// #pragma mark - Create Account
|
||||||
|
|
||||||
|
|
||||||
@@ -1357,3 +1444,27 @@ UserLoginWindow::_ViewUserUsageConditions()
|
|||||||
fModel, *fUserUsageConditions);
|
fModel, *fUserUsageConditions);
|
||||||
window->Show();
|
window->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
UserLoginWindow::_ViewPasswordRequirements()
|
||||||
|
{
|
||||||
|
if (fPasswordRequirements == NULL)
|
||||||
|
HDFATAL("the password requirements must have been setup");
|
||||||
|
BString msg = B_TRANSLATE("The password must be a minimum of "
|
||||||
|
"%MinPasswordLength% characters. "
|
||||||
|
"%MinPasswordUppercaseChar% characters must be upper-case and "
|
||||||
|
"%MinPasswordDigitsChar% characters must be digits.");
|
||||||
|
msg.ReplaceAll("%MinPasswordLength%",
|
||||||
|
BString() << fPasswordRequirements->MinPasswordLength());
|
||||||
|
msg.ReplaceAll("%MinPasswordUppercaseChar%",
|
||||||
|
BString() << fPasswordRequirements->MinPasswordUppercaseChar());
|
||||||
|
msg.ReplaceAll("%MinPasswordDigitsChar%",
|
||||||
|
BString() << fPasswordRequirements->MinPasswordDigitsChar());
|
||||||
|
|
||||||
|
BAlert* alert = new(std::nothrow) BAlert(
|
||||||
|
B_TRANSLATE("Password requirements"), msg, B_TRANSLATE("OK"));
|
||||||
|
|
||||||
|
if (alert != NULL)
|
||||||
|
alert->Go();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||||
* Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>.
|
* Copyright 2019-2023, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef USER_LOGIN_WINDOW_H
|
#ifndef USER_LOGIN_WINDOW_H
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "CreateUserDetail.h"
|
#include "CreateUserDetail.h"
|
||||||
#include "PackageInfo.h"
|
#include "PackageInfo.h"
|
||||||
|
#include "PasswordRequirements.h"
|
||||||
#include "UserCredentials.h"
|
#include "UserCredentials.h"
|
||||||
#include "ValidationFailure.h"
|
#include "ValidationFailure.h"
|
||||||
|
|
||||||
@@ -95,6 +96,8 @@ private:
|
|||||||
Captcha& captcha);
|
Captcha& captcha);
|
||||||
status_t _CreateAccountUserUsageConditionsSetupThread(
|
status_t _CreateAccountUserUsageConditionsSetupThread(
|
||||||
UserUsageConditions& userUsageConditions);
|
UserUsageConditions& userUsageConditions);
|
||||||
|
status_t _CreateAccountPasswordRequirementsSetupThread(
|
||||||
|
PasswordRequirements& passwordRequirements);
|
||||||
status_t _UnpackCaptcha(BMessage& responsePayload,
|
status_t _UnpackCaptcha(BMessage& responsePayload,
|
||||||
Captcha& captcha);
|
Captcha& captcha);
|
||||||
void _HandleCreateAccountSetupSuccess(
|
void _HandleCreateAccountSetupSuccess(
|
||||||
@@ -103,12 +106,15 @@ private:
|
|||||||
void _SetCaptcha(Captcha* captcha);
|
void _SetCaptcha(Captcha* captcha);
|
||||||
void _SetUserUsageConditions(
|
void _SetUserUsageConditions(
|
||||||
UserUsageConditions* userUsageConditions);
|
UserUsageConditions* userUsageConditions);
|
||||||
|
void _SetPasswordRequirements(
|
||||||
|
PasswordRequirements* passwordRequirements);
|
||||||
|
|
||||||
void _CollectValidationFailures(
|
void _CollectValidationFailures(
|
||||||
const BMessage& result,
|
const BMessage& result,
|
||||||
BString& error) const;
|
BString& error) const;
|
||||||
|
|
||||||
void _ViewUserUsageConditions();
|
void _ViewUserUsageConditions();
|
||||||
|
void _ViewPasswordRequirements();
|
||||||
|
|
||||||
void _TakeUpCredentialsAndQuit(
|
void _TakeUpCredentialsAndQuit(
|
||||||
const UserCredentials& credentials);
|
const UserCredentials& credentials);
|
||||||
@@ -131,6 +137,7 @@ private:
|
|||||||
BTextControl* fNewNicknameField;
|
BTextControl* fNewNicknameField;
|
||||||
BTextControl* fNewPasswordField;
|
BTextControl* fNewPasswordField;
|
||||||
BTextControl* fRepeatPasswordField;
|
BTextControl* fRepeatPasswordField;
|
||||||
|
LinkView* fPasswordRequirementsLink;
|
||||||
BTextControl* fEmailField;
|
BTextControl* fEmailField;
|
||||||
BMenuField* fLanguageCodeField;
|
BMenuField* fLanguageCodeField;
|
||||||
BitmapView* fCaptchaView;
|
BitmapView* fCaptchaView;
|
||||||
@@ -142,6 +149,8 @@ private:
|
|||||||
BButton* fSendButton;
|
BButton* fSendButton;
|
||||||
BButton* fCancelButton;
|
BButton* fCancelButton;
|
||||||
|
|
||||||
|
PasswordRequirements*
|
||||||
|
fPasswordRequirements;
|
||||||
UserUsageConditions*
|
UserUsageConditions*
|
||||||
fUserUsageConditions;
|
fUserUsageConditions;
|
||||||
Captcha* fCaptcha;
|
Captcha* fCaptcha;
|
||||||
|
|||||||
Reference in New Issue
Block a user