package domain import ( "strings" "time" ) const ( MetadataHeadlessLoginEnabled = "headless_login_enabled" MetadataHeadlessTokenEndpointAuthMethod = "headless_token_endpoint_auth_method" MetadataHeadlessJWKSURI = "headless_jwks_uri" MetadataHeadlessJWKS = "headless_jwks" MetadataRequestObjectSigningAlg = "request_object_signing_alg" MetadataIDTokenClaims = "id_token_claims" MetadataBackChannelLogoutURI = "backchannel_logout_uri" MetadataBackChannelLogoutSessionRequired = "backchannel_logout_session_required" MetadataAutoLoginSupported = "auto_login_supported" MetadataAutoLoginURL = "auto_login_url" ) type HydraClient struct { ClientID string `json:"client_id"` ClientName string `json:"client_name,omitempty"` ClientSecret string `json:"client_secret,omitempty"` // Added ClientURI string `json:"client_uri,omitempty"` RedirectURIs []string `json:"redirect_uris,omitempty"` GrantTypes []string `json:"grant_types,omitempty"` ResponseTypes []string `json:"response_types,omitempty"` Scope string `json:"scope,omitempty"` TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"` SkipConsent *bool `json:"skip_consent,omitempty"` JWKSUri string `json:"jwks_uri,omitempty"` JWKS any `json:"jwks,omitempty"` BackChannelLogoutURI string `json:"backchannel_logout_uri,omitempty"` BackChannelLogoutSessionRequired *bool `json:"backchannel_logout_session_required,omitempty"` Metadata map[string]any `json:"metadata,omitempty"` } func (c *HydraClient) SupportsHeadlessLogin() bool { // Headless login now supports jwksUri only. hasPublicKey := c.HeadlessJWKSURI() != "" isPrivateKeyJwt := c.HeadlessTokenEndpointAuthMethod() == "private_key_jwt" return hasPublicKey && isPrivateKeyJwt } func (c *HydraClient) HeadlessTokenEndpointAuthMethod() string { if c.Metadata != nil { if raw, ok := c.Metadata[MetadataHeadlessTokenEndpointAuthMethod].(string); ok { if value := strings.TrimSpace(raw); value != "" { return value } } } return strings.TrimSpace(c.TokenEndpointAuthMethod) } func (c *HydraClient) HeadlessJWKSURI() string { if c.Metadata != nil { if raw, ok := c.Metadata[MetadataHeadlessJWKSURI].(string); ok { if value := strings.TrimSpace(raw); value != "" { return value } } } return strings.TrimSpace(c.JWKSUri) } func (c *HydraClient) HeadlessJWKS() any { if c.Metadata != nil { if value, ok := c.Metadata[MetadataHeadlessJWKS]; ok && value != nil { return value } } return c.JWKS } func (c *HydraClient) IsHeadlessLoginEnabled() bool { if !c.SupportsHeadlessLogin() { return false } if c.Metadata == nil { return false } val, ok := c.Metadata[MetadataHeadlessLoginEnabled] if !ok { return false } if b, ok := val.(bool); ok { return b } return false } func (c *HydraClient) BackchannelLogoutURI() string { if c.Metadata != nil { if raw, ok := c.Metadata[MetadataBackChannelLogoutURI].(string); ok { if value := strings.TrimSpace(raw); value != "" { return value } } } return strings.TrimSpace(c.BackChannelLogoutURI) } func (c *HydraClient) BackchannelLogoutSessionRequiredValue() bool { if c.Metadata != nil { if raw, ok := c.Metadata[MetadataBackChannelLogoutSessionRequired].(bool); ok { return raw } } if c.BackChannelLogoutSessionRequired != nil { return *c.BackChannelLogoutSessionRequired } return false } type HydraConsentRequest struct { Challenge string `json:"challenge"` RequestedScope []string `json:"requested_scope"` RequestedAudience []string `json:"requested_access_token_audience"` Skip bool `json:"skip"` Subject string `json:"subject"` Client HydraClient `json:"client"` } type HydraLoginRequest struct { Challenge string `json:"challenge"` Subject string `json:"subject"` Skip bool `json:"skip"` Client HydraClient `json:"client"` } type HydraConsentSession struct { ConsentRequestID string `json:"consent_request_id,omitempty"` Subject string `json:"subject,omitempty"` GrantedScope []string `json:"grant_scope,omitempty"` GrantedAudience []string `json:"grant_access_token_audience,omitempty"` Remember bool `json:"remember"` RememberFor int `json:"remember_for,omitempty"` AuthenticatedAt *time.Time `json:"authenticated_at,omitempty"` RequestedAt *time.Time `json:"requested_at,omitempty"` HandledAt *time.Time `json:"handled_at,omitempty"` Client HydraClient `json:"client"` ConsentRequest *HydraConsentRequest `json:"consent_request,omitempty"` }