openSession method
Reopens the hub as a new session generation.
secret is required, and that is the whole point: reopening means
admitting a cohort, so the operator has to say which credential admits it.
Pass the same string to keep the old one — deliberately an explicit
choice, because the alternative is a hub that silently readmits everyone
who took part in the session you just ended. Bumping epoch alone would
not stop them: the epoch is announced in the challenge, so anyone still
holding the secret would simply prove against the new one.
Implementation
void openSession({required String secret, Duration? ttl}) {
if (secret.isEmpty) {
throw ArgumentError.value('<redacted>', 'secret', 'must not be empty');
}
final rotated = secret != _secret;
_epoch++;
_secret = secret;
_revoked.clear();
_status = HubSessionStatus.open;
_ttlTimer?.cancel();
_ttlTimer = null;
if (ttl != null) _armTtl(ttl);
logger.info(
'Session "$_session" open at epoch $_epoch'
'${rotated ? ' with a rotated secret' : ' reusing the previous secret'}',
);
}