* fix(auth): ignore a UserInfo response without a sub
fetch_userinfo() compared the UserInfo sub with the ID token's only when
it was truthy, so a response with no sub (or an empty one) was accepted
and its email, email_verified and name replaced the signed ID token's.
OIDC Core 5.3.2 requires the two subjects to match before UserInfo is
used. A missing, empty or non-string sub now raises OIDCUserInfoMismatch,
which the callback already treats as a skipped UserInfo request.
* fix(auth): log a non-string UserInfo sub apart from a missing one
The callback continues silently on a rejected UserInfo response, so the
log line is the only way to tell a provider that omits sub from one that
sends a malformed value. A non-string sub now reports its type.
* test(auth): name the UserInfo sub cases for what they cover
The case list and the callback test also cover a present but non-string
sub, so "no sub" undersold them.