internal/domain/passkey.go
Rama main · réplica de lectura del repositorio original.
package domain
import "errors"
// Passkey-related errors.
var (
ErrPasskeyChallengeInvalid = errors.New("passkey challenge invalid")
ErrPasskeyNotFound = errors.New("passkey not found")
ErrPasskeyInvalid = errors.New("passkey invalid")
ErrPasskeyUserHandleInvalid = errors.New("passkey user handle invalid")
)
// PasskeyChallengePurpose distinguishes a registration challenge from a login challenge.
type PasskeyChallengePurpose string
const (
PasskeyChallengeLogin PasskeyChallengePurpose = "login"
PasskeyChallengeRegister PasskeyChallengePurpose = "register"
)
// PasskeyChallenge is the metadata of a one-time WebAuthn challenge (short TTL, burn after use).
// A registration challenge is bound to the initiating user; a login (discoverable) challenge has UserID=0 and the user is looked up from user_handle.
type PasskeyChallenge struct {
Purpose PasskeyChallengePurpose
UserID int64
ExpiresAt int64 // unix seconds
}
// PasskeyCredential is a registered passkey credential (WebAuthn public key).
type PasskeyCredential struct {
CredentialID []byte // raw credential id bytes (exposed as base64url)
UserID int64
PublicKey []byte // raw COSE public key bytes
SignCount uint32
AAGUID []byte
Name string
Transports []string
CreatedAt int64 // unix seconds
LastUsedAt int64 // unix seconds; 0 means never used to log in
}
// Clone deep-copies the slice fields so the in-memory store never exposes internal references.
func (c PasskeyCredential) Clone() PasskeyCredential {
out := c
out.CredentialID = append([]byte(nil), c.CredentialID...)
out.PublicKey = append([]byte(nil), c.PublicKey...)
out.AAGUID = append([]byte(nil), c.AAGUID...)
out.Transports = append([]string(nil), c.Transports...)
return out
}