CoolCMS API

AccountDeletion
in package

FinalYes

Account deletion requested by the user — the pure rules shared by the Api manager, the cron and the tests. No I/O.

Life cycle of cms_system_users:

  1. (OAuth account without a password only) confirmation pending — deletion_token_* hold the hash of the e-mailed confirmation link (self::CONFIRM_TTL_SECONDS), no request yet,
  2. deletion requested — deletion_requested_at set, deletion_token_* hold the hash of the e-mailed cancel link valid until the end of the grace period, deletion_nonce the random version of this request; while the anonymization runs, deletion_claimed_at holds its claim,
  3. anonymized — deleted_at set, personal data wiped, the row stays for the references (orders, documents, posts).

Tokens follow PasswordResetToken: the plain token travels only in the e-mailed link, the database keeps its sha256.

Table of Contents

Constants

ANONYMIZED_EMAIL_DOMAIN  : string = 'anonymized.invalid'
Domain of the anonymized e-mail; `.invalid` is reserved (RFC 2606), nothing is ever delivered.
CLAIM_STALE_SECONDS  : int = 900
How long the anonymization claim of one run holds. A cancel is refused while the claim is fresh; a claim left behind by a crashed run goes stale after this and the account can be cancelled or claimed again (the module steps are idempotent).
CONFIRM_TTL_SECONDS  : int = 86400
Validity of the confirmation link for an account without a password (24 h).
DEFAULT_GRACE_DAYS  : int = 7
Grace period when the setting `account.deletion.graceDays` is missing or invalid.
MAX_GRACE_DAYS  : int = 365
Upper bound of the setting — a typo must not keep a requested deletion for years.

Methods

buildAnonymizedEmail()  : string
Unique placeholder e-mail of an anonymized account — frees the original address for a new registration while the unique index stays satisfied.
buildAnonymizedUsername()  : string
buildClaimStaleBefore()  : DateTime
Claims taken before this moment are stale ({@see self::CLAIM_STALE_SECONDS}).
buildConfirmExpiry()  : DateTime
buildDueBefore()  : DateTime
Requests made before this moment are past their grace period (cron cut-off).
buildScheduledAt()  : DateTime
When the account requested at `$requestedAt` gets anonymized.
buildUnusablePasswordHash()  : string
A value no password hash verifier accepts (not a bcrypt/argon string) — the anonymized account cannot sign in even if some gate were bypassed. Random, so it is not a constant anyone could recognise or reuse.
generateRequestNonce()  : string
Random version of one request (`deletion_nonce`, 32 hex).
generateToken()  : string
hashToken()  : string
isDue()  : bool
Has the grace period of a request made at `$requestedAt` passed?
isTokenValid()  : bool
Stored token still usable? Empty hash, missing or past expiry never matches.
normalizeGraceDays()  : int
Setting value → grace days within 1…{@see self::MAX_GRACE_DAYS}; anything else = default.

Constants

ANONYMIZED_EMAIL_DOMAIN

Domain of the anonymized e-mail; `.invalid` is reserved (RFC 2606), nothing is ever delivered.

public string ANONYMIZED_EMAIL_DOMAIN = 'anonymized.invalid'

CLAIM_STALE_SECONDS

How long the anonymization claim of one run holds. A cancel is refused while the claim is fresh; a claim left behind by a crashed run goes stale after this and the account can be cancelled or claimed again (the module steps are idempotent).

public int CLAIM_STALE_SECONDS = 900

CONFIRM_TTL_SECONDS

Validity of the confirmation link for an account without a password (24 h).

public int CONFIRM_TTL_SECONDS = 86400

DEFAULT_GRACE_DAYS

Grace period when the setting `account.deletion.graceDays` is missing or invalid.

public int DEFAULT_GRACE_DAYS = 7

MAX_GRACE_DAYS

Upper bound of the setting — a typo must not keep a requested deletion for years.

public int MAX_GRACE_DAYS = 365

Methods

buildAnonymizedEmail()

Unique placeholder e-mail of an anonymized account — frees the original address for a new registration while the unique index stays satisfied.

public static buildAnonymizedEmail(int $userId) : string
Parameters
$userId : int
Return values
string

buildAnonymizedUsername()

public static buildAnonymizedUsername(int $userId) : string
Parameters
$userId : int
Return values
string

buildClaimStaleBefore()

Claims taken before this moment are stale ({@see self::CLAIM_STALE_SECONDS}).

public static buildClaimStaleBefore(DateTimeInterface $now) : DateTime
Parameters
$now : DateTimeInterface
Return values
DateTime

buildConfirmExpiry()

public static buildConfirmExpiry(DateTimeInterface $now) : DateTime
Parameters
$now : DateTimeInterface
Return values
DateTime

buildDueBefore()

Requests made before this moment are past their grace period (cron cut-off).

public static buildDueBefore(DateTimeInterface $now, int $graceDays) : DateTime
Parameters
$now : DateTimeInterface
$graceDays : int
Return values
DateTime

buildScheduledAt()

When the account requested at `$requestedAt` gets anonymized.

public static buildScheduledAt(DateTimeInterface $requestedAt, int $graceDays) : DateTime
Parameters
$requestedAt : DateTimeInterface
$graceDays : int
Return values
DateTime

buildUnusablePasswordHash()

A value no password hash verifier accepts (not a bcrypt/argon string) — the anonymized account cannot sign in even if some gate were bypassed. Random, so it is not a constant anyone could recognise or reuse.

public static buildUnusablePasswordHash() : string
Return values
string

generateRequestNonce()

Random version of one request (`deletion_nonce`, 32 hex).

public static generateRequestNonce() : string

A new request, a cancel, the claim of the anonymization and the anonymization itself replace or clear it, so every ticket / claim bound to the previous value stops matching — even when deletion_requested_at (second precision) ends up the same.

Return values
string

generateToken()

public static generateToken() : string
Return values
string

hashToken()

public static hashToken(string $plainToken) : string
Parameters
$plainToken : string
Return values
string

isDue()

Has the grace period of a request made at `$requestedAt` passed?

public static isDue(DateTimeInterface|null $requestedAt, int $graceDays, DateTimeInterface $now) : bool
Parameters
$requestedAt : DateTimeInterface|null
$graceDays : int
$now : DateTimeInterface
Return values
bool

isTokenValid()

Stored token still usable? Empty hash, missing or past expiry never matches.

public static isTokenValid(string|null $storedHash, DateTimeInterface|null $expiresAt, DateTimeInterface $now) : bool
Parameters
$storedHash : string|null
$expiresAt : DateTimeInterface|null
$now : DateTimeInterface
Return values
bool

normalizeGraceDays()

Setting value → grace days within 1…{@see self::MAX_GRACE_DAYS}; anything else = default.

public static normalizeGraceDays(mixed $value) : int
Parameters
$value : mixed
Return values
int
On this page

Search results