CoolCMS API

ConfirmByKeyTrait

Confirms a record by its author with the key from the e-mail; shared logic for an advert (Bazaar), a company profile (Comcat) and a discussion post.

The e-mail with the link ?do=confirm&key=… is sent by the Api manager on insert when the module requires confirmation from the given kind of author (EmailConfirmationSetting). Security rests on the key (256 bits, only a digest in the database, AdvertConfirmationKey), not on a login, like account activation (UserManager::activateUser()); a guest author clicks the link too.

Contract of self::confirmByKey():

  • an unknown, deleted or banned record, an empty or wrong key and an exhausted limit give one answer (confirmationKeyInvalidCode() of the host; no oracle on the existence or state of a record),
  • a correct key of an unconfirmed record sets confirmedAt = now, consumes the key (only a "consumed" digest stays in the database, which confirms nothing anymore) and then runs the follow-ups (afterRecordConfirmed() of the host),
  • an already confirmed record with a correct key succeeds without change (a repeated click from the mailbox is not an error); with a wrong key it gives the same error as above,
  • limit: failed attempts per record and per IP (ratelimit.advertConfirm, shared by all modules, limit keys separated by module); a correct key does not spend the quota. Once exhausted, even a correct key is rejected until the window expires.

No e-mail is sent after the confirmation.

Requires in the using class:

  • $this->rateLimit (RateLimit), $this->rateLimitConfig (RateLimitConfig),
  • findRecordForConfirmation(int), the Shared advert, profile or post entity or null, read fresh from the database (without the query cache a consumed key could be used again),
  • updateConfirmationColumns(int, array): Result, a write through the Api manager (cache bump),
  • afterRecordConfirmed(int): void, the follow-ups after the write (search index, category counts...),
  • getConfirmModule(): string (bazaar | comcat | discussion), used only in limit keys and the log,
  • confirmationKeyInvalidCode(): ResultCode, the code of the uniform error answer.

Advert modules use it through AdvertConfirmByKeyTrait (hook names kept).

Table of Contents

Constants

CONFIRM_KEY_MAX_LENGTH  : int = 128
Input longer than any issued key is not even looked up (64 hex characters).

Methods

confirmByKey()  : Result
confirmIpLimitKey()  : string
confirmRecordLimitKey()  : string
The limit keys keep the format from when the trait knew only adverts (`advert-confirm:<module>:advert:<id>`).
passesConfirmLimit()  : bool
Peeks without incrementing: only failed attempts spend the quota ({@see self::rejectConfirmation()}).
rejectConfirmation()  : Result

Constants

CONFIRM_KEY_MAX_LENGTH

Input longer than any issued key is not even looked up (64 hex characters).

private int CONFIRM_KEY_MAX_LENGTH = 128

Methods

confirmByKey()

public confirmByKey(int $id, string $key, string|null $ip) : Result
Parameters
$id : int
$key : string
$ip : string|null
Return values
Result

confirmIpLimitKey()

private confirmIpLimitKey(string|null $ip) : string
Parameters
$ip : string|null
Return values
string

confirmRecordLimitKey()

The limit keys keep the format from when the trait knew only adverts (`advert-confirm:<module>:advert:<id>`).

private confirmRecordLimitKey(int $id) : string
Parameters
$id : int
Return values
string

passesConfirmLimit()

Peeks without incrementing: only failed attempts spend the quota ({@see self::rejectConfirmation()}).

private passesConfirmLimit(int $id, string|null $ip) : bool
Parameters
$id : int
$ip : string|null
Return values
bool

rejectConfirmation()

private rejectConfirmation(int $id, string|null $ip) : Result
Parameters
$id : int
$ip : string|null
Return values
Result
On this page

Search results