// Copyright (c) Abstract Machines // SPDX-License-Identifier: Apache-2.0 package auth import ( "context" "time" "github.com/absmach/magistrala/pkg/errors" ) var ( ErrUnsupportedKeyAlgorithm = errors.New("unsupported key algorithm") ErrInvalidSymmetricKey = errors.New("invalid symmetric key") ErrPublicKeysNotSupported = errors.New("public keys not supported for symmetric algorithm") ErrRevokedToken = errors.NewAuthNError("token is revoked") ) // PublicKeyInfo represents a public key for external distribution via JWKS. // This follows RFC 7517 (JSON Web Key) specification. type PublicKeyInfo struct { KeyID string `json:"kid"` KeyType string `json:"kty"` Algorithm string `json:"alg"` Use string `json:"use,omitempty"` // EdDSA (Ed25519) fields Curve string `json:"crv,omitempty"` X string `json:"x,omitempty"` // Future: RSA fields (n, e), ECDSA fields (x, y, crv), etc. } // Tokenizer handles token creation and verification for authentication. // Implementations manage underlying cryptographic operations and key distribution. type Tokenizer interface { // Issue creates a signed token string from the given key claims. // For RefreshKey types, the token ID is stored as active in the cache. Issue(key Key) (token string, err error) // Parse verifies and parses a token string (JWT or PAT), returning the extracted claims. // For PAT tokens (prefix "pat"), returns a Key with Type set to PersonalAccessToken. // For JWT tokens, performs cryptographic verification and returns the parsed claims. Parse(ctx context.Context, token string) (key Key, err error) // RetrieveJWKS returns public keys for distribution via JWKS endpoint. // Returns ErrPublicKeysNotSupported for symmetric tokenizers (HMAC). RetrieveJWKS() ([]PublicKeyInfo, error) } // UserActiveTokensCache represents a cache repository for managing active refresh tokens per user. type UserActiveTokensCache interface { // SaveActive saves an active refresh token ID for a user with optional description. SaveActive(ctx context.Context, userID, tokenID, description string, expiry time.Time) error // IsActive checks if the token ID is active. IsActive(ctx context.Context, tokenID string) (bool, error) // ListUserTokens lists all active token IDs with descriptions for a given user. ListUserTokens(ctx context.Context, userID string) ([]TokenInfo, error) // RemoveActive removes an active refresh token ID. RemoveActive(ctx context.Context, userID, tokenID string) error } // TokenInfo represents information about an active refresh token. type TokenInfo struct { ID string `json:"id"` Description string `json:"description,omitempty"` } // IsSymmetricAlgorithm determines if the given algorithm is symmetric (HMAC-based). // Returns true for HMAC algorithms (HS256, HS384, HS512). // Returns false for asymmetric algorithms (EdDSA). // Returns error for unsupported algorithms. func IsSymmetricAlgorithm(alg string) (bool, error) { switch alg { case "EdDSA": return false, nil case "HS256", "HS384", "HS512": return true, nil default: return false, ErrUnsupportedKeyAlgorithm } }