Fix encoding errors and comment class helper
This commit is contained in:
parent
16e64dba3b
commit
5d10fcbf54
2 changed files with 60 additions and 6 deletions
|
@ -4279,8 +4279,9 @@ App::post('/v1/account/mfa/authenticators/webauthn')
|
||||||
$authenticators = array_filter($user->getAttribute('authenticators', []), fn ($authenticator) => $authenticator['type'] === Type::WEBAUTHN);
|
$authenticators = array_filter($user->getAttribute('authenticators', []), fn ($authenticator) => $authenticator['type'] === Type::WEBAUTHN);
|
||||||
|
|
||||||
foreach ($authenticators as $authenticator) {
|
foreach ($authenticators as $authenticator) {
|
||||||
if (empty($authenticator['verified'])) {
|
/** @var Document $authenticator */
|
||||||
$dbForProject->deleteDocument('authenticators', $authenticator['id']);
|
if (empty($authenticator->getAttribute('verified', false))) {
|
||||||
|
$dbForProject->deleteDocument('authenticators', $authenticator->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4295,7 +4296,7 @@ App::post('/v1/account/mfa/authenticators/webauthn')
|
||||||
'userInternalId' => $user->getInternalId(),
|
'userInternalId' => $user->getInternalId(),
|
||||||
'type' => Type::WEBAUTHN,
|
'type' => Type::WEBAUTHN,
|
||||||
'verified' => false,
|
'verified' => false,
|
||||||
'data' => $challenge->jsonSerialize(),
|
'data' => json_encode($challenge),
|
||||||
'$permissions' => [
|
'$permissions' => [
|
||||||
Permission::read(Role::user($user->getId())),
|
Permission::read(Role::user($user->getId())),
|
||||||
Permission::update(Role::user($user->getId())),
|
Permission::update(Role::user($user->getId())),
|
||||||
|
@ -4360,7 +4361,7 @@ App::put('/v1/account/mfa/authenticators/webauthn')
|
||||||
}
|
}
|
||||||
|
|
||||||
$authenticator->setAttribute('verified', true);
|
$authenticator->setAttribute('verified', true);
|
||||||
$authenticator->setAttribute('data', $publicKeyCredentials->jsonSerialize());
|
$authenticator->setAttribute('data', json_encode($publicKeyCredentials));
|
||||||
$dbForProject->updateDocument('authenticators', $authenticator->getId(), $authenticator);
|
$dbForProject->updateDocument('authenticators', $authenticator->getId(), $authenticator);
|
||||||
|
|
||||||
$factors = $session->getAttribute('factors', []);
|
$factors = $session->getAttribute('factors', []);
|
||||||
|
|
|
@ -43,6 +43,13 @@ class WebAuthn extends Type
|
||||||
$this->authenticatiorAssertionResponseValdiator = AuthenticatorAssertionResponseValidator::create();
|
$this->authenticatiorAssertionResponseValdiator = AuthenticatorAssertionResponseValidator::create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new relying party entity, uses the platform if possible
|
||||||
|
*
|
||||||
|
* @param Document $project
|
||||||
|
* @param Request $request
|
||||||
|
* @return PublicKeyCredentialRpEntity
|
||||||
|
*/
|
||||||
public static function createRelyingParty(Document $project, Request $request): PublicKeyCredentialRpEntity
|
public static function createRelyingParty(Document $project, Request $request): PublicKeyCredentialRpEntity
|
||||||
{
|
{
|
||||||
// Calculate Relying Party ID and Name
|
// Calculate Relying Party ID and Name
|
||||||
|
@ -113,6 +120,12 @@ class WebAuthn extends Type
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user entity from an Appwrite user document
|
||||||
|
*
|
||||||
|
* @param Document $user
|
||||||
|
* @return PublicKeyCredentialUserEntity
|
||||||
|
*/
|
||||||
public static function createUserEntity(Document $user): PublicKeyCredentialUserEntity
|
public static function createUserEntity(Document $user): PublicKeyCredentialUserEntity
|
||||||
{
|
{
|
||||||
$name = $user->getAttribute('name') ?? $user->getAttribute('email');
|
$name = $user->getAttribute('name') ?? $user->getAttribute('email');
|
||||||
|
@ -124,23 +137,39 @@ class WebAuthn extends Type
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new register challenge
|
||||||
|
*
|
||||||
|
* @param PublicKeyCredentialRpEntity $rpEntity
|
||||||
|
* @param PublicKeyCredentialUserEntity $userEntity
|
||||||
|
* @param int $timeout Timeout in seconds
|
||||||
|
* @return PublicKeyCredentialCreationOptions
|
||||||
|
*/
|
||||||
public static function createRegisterChallenge(PublicKeyCredentialRpEntity $rpEntity, PublicKeyCredentialUserEntity $userEntity, int $timeout): PublicKeyCredentialCreationOptions
|
public static function createRegisterChallenge(PublicKeyCredentialRpEntity $rpEntity, PublicKeyCredentialUserEntity $userEntity, int $timeout): PublicKeyCredentialCreationOptions
|
||||||
{
|
{
|
||||||
return PublicKeyCredentialCreationOptions::create(
|
return PublicKeyCredentialCreationOptions::create(
|
||||||
rp: $rpEntity,
|
rp: $rpEntity,
|
||||||
user: $userEntity,
|
user: $userEntity,
|
||||||
challenge: random_bytes(32),
|
challenge: random_bytes(32),
|
||||||
timeout: $timeout
|
timeout: $timeout * 1000, // Convert seconds to milliseconds
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new login challenge
|
||||||
|
*
|
||||||
|
* @param PublicKeyCredentialRpEntity $rpEntity
|
||||||
|
* @param PublicKeyCredentialSource[] $allowedCredentials
|
||||||
|
* @param int $timeout Timeout in seconds
|
||||||
|
* @return PublicKeyCredentialRequestOptions
|
||||||
|
*/
|
||||||
public static function createLoginChallenge(PublicKeyCredentialRpEntity $rpEntity, array $allowedCredentials, int $timeout): PublicKeyCredentialRequestOptions
|
public static function createLoginChallenge(PublicKeyCredentialRpEntity $rpEntity, array $allowedCredentials, int $timeout): PublicKeyCredentialRequestOptions
|
||||||
{
|
{
|
||||||
return PublicKeyCredentialRequestOptions::create(
|
return PublicKeyCredentialRequestOptions::create(
|
||||||
rpId: $rpEntity->id,
|
rpId: $rpEntity->id,
|
||||||
userVerification: PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_DEFAULT,
|
userVerification: PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_DEFAULT,
|
||||||
challenge: random_bytes(32),
|
challenge: random_bytes(32),
|
||||||
timeout: $timeout,
|
timeout: $timeout * 1000,
|
||||||
allowCredentials: $allowedCredentials
|
allowCredentials: $allowedCredentials
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -160,6 +189,10 @@ class WebAuthn extends Type
|
||||||
{
|
{
|
||||||
$authenticators = self::getAuthenticatorsFromUser($user);
|
$authenticators = self::getAuthenticatorsFromUser($user);
|
||||||
|
|
||||||
|
if (empty($authenticators)) {
|
||||||
|
throw new Exception(Exception::USER_AUTHENTICATOR_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
$authenticators = array_filter($authenticators, function ($authenticator) {
|
$authenticators = array_filter($authenticators, function ($authenticator) {
|
||||||
/** @var Document $authenticator */
|
/** @var Document $authenticator */
|
||||||
return $authenticator->getAttribute('verified') === true;
|
return $authenticator->getAttribute('verified') === true;
|
||||||
|
@ -176,6 +209,12 @@ class WebAuthn extends Type
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Verify a register challenge
|
||||||
|
*
|
||||||
|
* @param array $challenge The challenge data deserialized from the database
|
||||||
|
* @param string $challengeResponse The challenge response from the client
|
||||||
|
*
|
||||||
|
* @return PublicKeyCredentialSource
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function verifyRegisterChallenge(array $challenge, string $challengeResponse): PublicKeyCredentialSource
|
public function verifyRegisterChallenge(array $challenge, string $challengeResponse): PublicKeyCredentialSource
|
||||||
|
@ -208,6 +247,13 @@ class WebAuthn extends Type
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Verify a login challenge
|
||||||
|
*
|
||||||
|
* @param array $challenge The challenge data deserialized from the database
|
||||||
|
* @param string $challengeResponse The challenge response from the client
|
||||||
|
* @param string $hostname The hostname of the request
|
||||||
|
* @param PublicKeyCredentialSource $authenticatorPublicKey The public key of the authenticator
|
||||||
|
*
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function verifyLoginChallenge(array $challenge, string $challengeResponse, string $hostname, PublicKeyCredentialSource $authenticatorPublicKey): PublicKeyCredentialSource
|
public function verifyLoginChallenge(array $challenge, string $challengeResponse, string $hostname, PublicKeyCredentialSource $authenticatorPublicKey): PublicKeyCredentialSource
|
||||||
|
@ -235,6 +281,13 @@ class WebAuthn extends Type
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all authenticators from a user
|
||||||
|
*
|
||||||
|
* @param Document $user
|
||||||
|
* @return Document[]|null
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static function getAuthenticatorsFromUser(Document $user): ?array
|
public static function getAuthenticatorsFromUser(Document $user): ?array
|
||||||
{
|
{
|
||||||
$authenticators = array_filter($user->getAttribute('authenticators', []), function ($authenticator) {
|
$authenticators = array_filter($user->getAttribute('authenticators', []), function ($authenticator) {
|
||||||
|
|
Loading…
Reference in a new issue