oauth2

package module
v0.0.0-...-cb64155 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2026 License: MIT Imports: 38 Imported by: 0

README

PocketBase OAuth2 Provider Plugin

Turn any PocketBase instance into a fully compliant OAuth 2.0 Authorization Server with OpenID Connect support. Built on top of ory/fosite, the widely adopted, security-first OAuth 2.0 SDK for Go.

Features
  • Authorization Code Grant with PKCE enforcement
  • OpenID Connect (Implicit, Hybrid, and Refresh flows)
  • OpenID Connect Discovery (OIDC Discovery 1.0)
  • Token Revocation (RFC 7009)
  • Token Introspection (RFC 7662)
  • Dynamic Client Registration (RFC 7591) — optional
  • Authorization Server Metadata (RFC 8414)
  • Protected Resource Metadata (RFC 9728)
  • JWK Public Key Discovery (RFC 7517)
Requirements
  • Go 1.25+
  • PocketBase v0.36+
Installation
go get github.com/benjamesfleming/pocketbase-ext-oauth2
Quick Start
package main

import (
	"log"
	"os"
	"time"

	oauth2 "github.com/benjamesfleming/pocketbase-ext-oauth2"
	"github.com/pocketbase/pocketbase"
)

func main() {
	app := pocketbase.New()
	app.RootCmd.ParseFlags(os.Args[1:])

	oauth2.MustRegister(app, &oauth2.Config{
		BaseConfig: &oauth2.BaseConfig{
			AccessTokenLifespan:   time.Hour,
			AuthorizeCodeLifespan: time.Minute * 15,
			EnforcePKCE:           true,
			RefreshTokenScopes:    []string{}, // allow all scopes for refresh tokens
		},
		PathPrefix:                             "/oauth2",
		UserCollection:                         "users",
		EnableRFC7591DynamicClientRegistration: true,
		EnableRFC9728ProtectedResourceMetadata: true,
	})

	if err := app.Start(); err != nil {
		log.Fatal(err)
	}
}

The plugin will automatically run its database migrations on first boot, creating the required system collections.

Endpoints

All OAuth2 endpoints are served under the configured PathPrefix (default /oauth2).

Method Path Description
GET/POST /oauth2/auth Authorization endpoint
GET/POST /oauth2/token Token endpoint
POST /oauth2/revoke Token revocation
POST /oauth2/introspect Token introspection
GET /oauth2/userinfo OpenID Connect UserInfo
POST /oauth2/register Dynamic client registration (RFC 7591, optional)
GET /oauth2/login Built-in login/consent UI
Discovery & Metadata
Method Path Description
GET /.well-known/oauth-authorization-server Authorization Server Metadata (RFC 8414)
GET /.well-known/openid-configuration OpenID Connect Discovery
GET /.well-known/jwks.json JSON Web Key Set
GET /.well-known/oauth-protected-resource/{resource} Protected Resource Metadata (RFC 9728, optional)
How It Works
Access Tokens

Access tokens issued by this plugin are native PocketBase auth tokens. This means any PocketBase endpoint or middleware that accepts a standard auth token will work out of the box with OAuth2-issued access tokens — no additional configuration needed.

Key Management

On first bootstrap the plugin generates an Ed25519 signing key pair and a global HMAC secret, both stored in PocketBase's internal _params table. These persist across restarts and are used for signing ID tokens, authorization codes, and refresh tokens respectively.

Session Storage

OAuth2 session data (authorization codes, access tokens, refresh tokens, PKCE challenges, and OpenID Connect sessions) is stored in dedicated system collections that are automatically created by the plugin's migration. A cron job runs every hour to clean up expired sessions.

The plugin creates the following system collections automatically:

Collection Purpose
_oauth2Clients Registered OAuth2 client applications
_oauth2AuthCode Authorization code sessions
_oauth2Access Access token sessions
_oauth2Refresh Refresh token sessions
_oauth2PKCE PKCE challenge data
_oauth2OpenID OpenID Connect sessions
_oauth2JTI JWT Token Identifiers (for replay protection)
Custom UserInfo Claims

By default the /userinfo endpoint attempt a best-effort extraction of default OpenID claims from the authenticated user's PocketBase auth record. If you have non-standard column names or other requirements, you can customize the claim response by implementing the UserInfoClaimStrategy interface and returning any struct or map — it will be JSON-encoded in the /userinfo response.

type MyCustomClaims struct {
    Sub   string `json:"sub"`
    Email string `json:"email"`
}

type MyClaimStrategy struct{}

func (s *MyClaimStrategy) GetUserInfoClaims(e *core.RequestEvent, scopes []string) (interface{}, error) {
	// Return any struct or map — it will be JSON-encoded
	// in the /userinfo response.
	return &MyCustomClaims{
        Sub:   e.Auth.ID,
        Email: e.Auth.GetString("email"),
	}, nil
}

oauth2.MustRegister(app, &oauth2.Config{
	// ...
	UserInfoClaimStrategy: &MyClaimStrategy{},
})
Protected Resource Metadata (RFC 9728)

You can register additional protected resources so clients can discover your resource server metadata:

oauth2.RegisterProtectedResourceMetadata(
	&rfc9728.ProtectedResourceMetadata{
		Resource:               "https://api.example.com/data",
		AuthorizationServers:   []string{"https://auth.example.com"},
		BearerMethodsSupported: []string{"header"},
		ScopesSupported:        []string{"read", "write"},
	},
)

The metadata will be available at /.well-known/oauth-protected-resource/data.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsRegistered

func IsRegistered() bool

func MustRegister

func MustRegister(app core.App, config *Config)

func NewClientFromRFC7591Metadata

func NewClientFromRFC7591Metadata(app core.App, md *RFC7591ClientMetadataRequest) (*client.Client, string, error)

func Register

func Register(app core.App, config *Config) error

func RegisterProtectedResourceMetadata

func RegisterProtectedResourceMetadata(md *rfc9728.ProtectedResourceMetadata)

func ResetGlobalStateForTests

func ResetGlobalStateForTests()

ResetGlobalStateForTests resets the package-level global variables so each test gets a clean slate.

Types

type AccessTokenModel

type AccessTokenModel struct {
	BaseSessionModel
}

func (*AccessTokenModel) GetCollectionName

func (p *AccessTokenModel) GetCollectionName() string

type AuthCodeModel

type AuthCodeModel struct {
	BaseSessionModel
}

func (*AuthCodeModel) GetCollectionName

func (p *AuthCodeModel) GetCollectionName() string

type BaseConfig

type BaseConfig = fosite.Config

type BaseSessionModel

type BaseSessionModel struct {
	core.BaseRecordProxy
}

func (BaseSessionModel) GetClientID

func (m BaseSessionModel) GetClientID() string

func (BaseSessionModel) GetExpiresAt

func (m BaseSessionModel) GetExpiresAt() *time.Time

func (BaseSessionModel) GetFormData

func (m BaseSessionModel) GetFormData() string

func (BaseSessionModel) GetGrantedAudience

func (m BaseSessionModel) GetGrantedAudience() []string

func (BaseSessionModel) GetGrantedScopes

func (m BaseSessionModel) GetGrantedScopes() []string

func (BaseSessionModel) GetID

func (m BaseSessionModel) GetID() string

func (BaseSessionModel) GetRequestID

func (m BaseSessionModel) GetRequestID() string

func (BaseSessionModel) GetRequestedAt

func (m BaseSessionModel) GetRequestedAt() time.Time

func (BaseSessionModel) GetRequestedAudience

func (m BaseSessionModel) GetRequestedAudience() []string

func (BaseSessionModel) GetScopes

func (m BaseSessionModel) GetScopes() []string

func (BaseSessionModel) GetSessionData

func (m BaseSessionModel) GetSessionData() []byte

func (BaseSessionModel) GetSubject

func (m BaseSessionModel) GetSubject() string

func (BaseSessionModel) SetRequester

func (m BaseSessionModel) SetRequester(requester fosite.Requester, tokenType fosite.TokenType) error

func (BaseSessionModel) SetSignature

func (m BaseSessionModel) SetSignature(signature string)

func (BaseSessionModel) ToRequest

func (m BaseSessionModel) ToRequest(ctx context.Context, s *OAuth2Store, session fosite.Session) (*fosite.Request, error)

type ClientModel

type ClientModel struct {
	core.BaseRecordProxy
}

func NewClientModel

func NewClientModel(app core.App) *ClientModel

func (*ClientModel) ToClient

func (m *ClientModel) ToClient() (*client.Client, error)

type Config

type Config struct {
	*BaseConfig

	PathPrefix                             string
	UserCollection                         string
	UserInfoClaimStrategy                  UserInfoClaimStrategy
	EnableRFC7591DynamicClientRegistration bool
	EnableRFC9728ProtectedResourceMetadata bool
}

func GetOAuth2Config

func GetOAuth2Config() *Config

type DefaultUserInfoClaimStrategy

type DefaultUserInfoClaimStrategy struct{}

func (*DefaultUserInfoClaimStrategy) GetUserInfoClaims

func (d *DefaultUserInfoClaimStrategy) GetUserInfoClaims(e *core.RequestEvent, scopes []string) (interface{}, error)

GetUserInfoClaims implements UserInfoClaimStrategy.

type JTIModel

type JTIModel struct {
	core.BaseRecordProxy
}

func NewJTIModel

func NewJTIModel(app core.App) *JTIModel

type OAuth2Store

type OAuth2Store struct {
	// contains filtered or unexported fields
}

func GetOAuth2Store

func GetOAuth2Store() *OAuth2Store

func NewOAuth2Store

func NewOAuth2Store(app core.App) *OAuth2Store

func (*OAuth2Store) ClientAssertionJWTValid

func (s *OAuth2Store) ClientAssertionJWTValid(ctx context.Context, jti string) error

ClientAssertionJWTValid implements fosite.ClientManager.

func (*OAuth2Store) CreateAccessTokenSession

func (s *OAuth2Store) CreateAccessTokenSession(ctx context.Context, signature string, request fosite.Requester) (err error)

CreateAccessTokenSession implements oauth2.AccessTokenStorage.

func (*OAuth2Store) CreateAuthorizeCodeSession

func (s *OAuth2Store) CreateAuthorizeCodeSession(ctx context.Context, code string, request fosite.Requester) (err error)

CreateAuthorizeCodeSession implements oauth2.AuthorizeCodeStorage.

func (*OAuth2Store) CreateOpenIDConnectSession

func (s *OAuth2Store) CreateOpenIDConnectSession(ctx context.Context, authorizeCode string, requester fosite.Requester) error

CreateOpenIDConnectSession implements openid.OpenIDConnectRequestStorage.

func (*OAuth2Store) CreatePKCERequestSession

func (s *OAuth2Store) CreatePKCERequestSession(ctx context.Context, signature string, requester fosite.Requester) error

CreatePKCERequestSession implements [pkce.PKCERequestStorage].

func (*OAuth2Store) CreateRefreshTokenSession

func (s *OAuth2Store) CreateRefreshTokenSession(ctx context.Context, signature string, accessSignature string, request fosite.Requester) (err error)

CreateRefreshTokenSession implements oauth2.RefreshTokenStorage.

func (*OAuth2Store) DeleteAccessTokenSession

func (s *OAuth2Store) DeleteAccessTokenSession(ctx context.Context, signature string) (err error)

DeleteAccessTokenSession implements oauth2.AccessTokenStorage.

func (*OAuth2Store) DeleteOpenIDConnectSession

func (s *OAuth2Store) DeleteOpenIDConnectSession(ctx context.Context, authorizeCode string) error

DeleteOpenIDConnectSession implements openid.OpenIDConnectRequestStorage.

func (*OAuth2Store) DeletePKCERequestSession

func (s *OAuth2Store) DeletePKCERequestSession(ctx context.Context, signature string) error

DeletePKCERequestSession implements [pkce.PKCERequestStorage].

func (*OAuth2Store) DeleteRefreshTokenSession

func (s *OAuth2Store) DeleteRefreshTokenSession(ctx context.Context, signature string) (err error)

DeleteRefreshTokenSession implements oauth2.RefreshTokenStorage.

func (*OAuth2Store) GetAccessTokenSession

func (s *OAuth2Store) GetAccessTokenSession(ctx context.Context, signature string, session fosite.Session) (request fosite.Requester, err error)

GetAccessTokenSession implements oauth2.AccessTokenStorage.

func (*OAuth2Store) GetAuthorizeCodeSession

func (s *OAuth2Store) GetAuthorizeCodeSession(ctx context.Context, code string, session fosite.Session) (request fosite.Requester, err error)

GetAuthorizeCodeSession implements oauth2.AuthorizeCodeStorage.

func (*OAuth2Store) GetClient

func (s *OAuth2Store) GetClient(ctx context.Context, id string) (fosite.Client, error)

GetClient implements fosite.ClientManager.

func (*OAuth2Store) GetOpenIDConnectSession

func (s *OAuth2Store) GetOpenIDConnectSession(ctx context.Context, authorizeCode string, requester fosite.Requester) (fosite.Requester, error)

GetOpenIDConnectSession implements openid.OpenIDConnectRequestStorage.

func (*OAuth2Store) GetPKCERequestSession

func (s *OAuth2Store) GetPKCERequestSession(ctx context.Context, signature string, session fosite.Session) (fosite.Requester, error)

GetPKCERequestSession implements [pkce.PKCERequestStorage].

func (*OAuth2Store) GetRefreshTokenSession

func (s *OAuth2Store) GetRefreshTokenSession(ctx context.Context, signature string, session fosite.Session) (request fosite.Requester, err error)

GetRefreshTokenSession implements oauth2.RefreshTokenStorage.

func (*OAuth2Store) InvalidateAuthorizeCodeSession

func (s *OAuth2Store) InvalidateAuthorizeCodeSession(ctx context.Context, code string) (err error)

InvalidateAuthorizeCodeSession implements oauth2.AuthorizeCodeStorage.

func (*OAuth2Store) RegisterClient

func (s *OAuth2Store) RegisterClient(ctx context.Context, client *RFC7591ClientMetadataRequest) (fosite.Client, string, error)

RegisterClient implements RFC7591ClientStorage.

func (*OAuth2Store) RevokeAccessToken

func (s *OAuth2Store) RevokeAccessToken(ctx context.Context, requestID string) error

RevokeAccessToken implements oauth2.AccessTokenStorage.

func (*OAuth2Store) RevokeRefreshToken

func (s *OAuth2Store) RevokeRefreshToken(ctx context.Context, requestID string) error

RevokeRefreshToken implements oauth2.RefreshTokenStorage.

func (*OAuth2Store) RotateRefreshToken

func (s *OAuth2Store) RotateRefreshToken(ctx context.Context, requestID string, refreshTokenSignature string) (err error)

RotateRefreshToken implements oauth2.RefreshTokenStorage.

func (*OAuth2Store) SetClientAssertionJWT

func (s *OAuth2Store) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error

SetClientAssertionJWT implements fosite.ClientManager.

type OpenIDConnectSessionModel

type OpenIDConnectSessionModel struct {
	BaseSessionModel
}

func (*OpenIDConnectSessionModel) GetCollectionName

func (p *OpenIDConnectSessionModel) GetCollectionName() string

type PKCEModel

type PKCEModel struct {
	BaseSessionModel
}

func (*PKCEModel) GetCollectionName

func (p *PKCEModel) GetCollectionName() string

type PocketBaseStrategy

type PocketBaseStrategy struct {
	App    core.App
	Config interface {
		fosite.AccessTokenIssuerProvider
		fosite.AccessTokenLifespanProvider
		fosite.JWTScopeFieldProvider
	}
	HMACSHAStrategy fositeoauth2.CoreStrategy
}

func NewPocketBaseStrategy

func NewPocketBaseStrategy(app core.App, config fosite.Configurator) *PocketBaseStrategy

func (*PocketBaseStrategy) AccessTokenSignature

func (s *PocketBaseStrategy) AccessTokenSignature(ctx context.Context, token string) string

AccessTokenSignature implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) AuthorizeCodeSignature

func (s *PocketBaseStrategy) AuthorizeCodeSignature(ctx context.Context, token string) string

AuthorizeCodeSignature implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) GenerateAccessToken

func (s *PocketBaseStrategy) GenerateAccessToken(ctx context.Context, requester fosite.Requester) (token string, signature string, err error)

GenerateAccessToken implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) GenerateAuthorizeCode

func (s *PocketBaseStrategy) GenerateAuthorizeCode(ctx context.Context, requester fosite.Requester) (token string, signature string, err error)

GenerateAuthorizeCode implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) GenerateRefreshToken

func (s *PocketBaseStrategy) GenerateRefreshToken(ctx context.Context, requester fosite.Requester) (token string, signature string, err error)

GenerateRefreshToken implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) RefreshTokenSignature

func (s *PocketBaseStrategy) RefreshTokenSignature(ctx context.Context, token string) string

RefreshTokenSignature implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) ValidateAccessToken

func (s *PocketBaseStrategy) ValidateAccessToken(ctx context.Context, requester fosite.Requester, token string) error

ValidateAccessToken implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) ValidateAuthorizeCode

func (s *PocketBaseStrategy) ValidateAuthorizeCode(ctx context.Context, requester fosite.Requester, token string) (err error)

ValidateAuthorizeCode implements oauth2.CoreStrategy.

func (*PocketBaseStrategy) ValidateRefreshToken

func (s *PocketBaseStrategy) ValidateRefreshToken(ctx context.Context, requester fosite.Requester, token string) (err error)

ValidateRefreshToken implements oauth2.CoreStrategy.

type RFC7591ClientMetadata

type RFC7591ClientMetadata struct {
	RFC7591ClientMetadataRequest
	ClientID              string `json:"client_id"`
	ClientSecret          string `json:"client_secret"`
	ClientSecretExpiresAt int64  `json:"client_secret_expires_at"`
}

type RFC7591ClientMetadataRequest

type RFC7591ClientMetadataRequest struct {
	Scope                   string              `json:"scope"`
	RedirectURIs            []string            `json:"redirect_uris"`
	TokenEndpointAuthMethod string              `json:"token_endpoint_auth_method"`
	GrantTypes              []string            `json:"grant_types"`
	ResponseTypes           []string            `json:"response_types"`
	Contacts                []string            `json:"contacts,omitempty"`
	ClientName              string              `json:"client_name"`
	ClientURI               string              `json:"client_uri,omitempty"`
	LogoURI                 string              `json:"logo_uri,omitempty"`
	TermsOfServiceURI       string              `json:"tos_uri,omitempty"`
	PolicyURI               string              `json:"policy_uri,omitempty"`
	JwksURI                 string              `json:"jwks_uri,omitempty"`
	Jwks                    *jose.JSONWebKeySet `json:"jwks,omitempty"`
	SoftwareID              string              `json:"software_id,omitempty"`
	SoftwareVersion         string              `json:"software_version,omitempty"`

	// The following fields are not part of the RFC7591 but are required for OpenID Connect client registration.
	// @ref https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.6.2
	RequestURIs []string `json:"request_uris,omitempty"`
}

type RFC7591ClientStorage

type RFC7591ClientStorage interface {
	// RegisterClient registers a new client with the given metadata
	// and returns the created client or an error if the registration failed.
	RegisterClient(ctx context.Context, client *RFC7591ClientMetadataRequest) (fosite.Client, string, error)
}

type RefreshTokenModel

type RefreshTokenModel struct {
	BaseSessionModel
}

func (*RefreshTokenModel) GetCollectionName

func (p *RefreshTokenModel) GetCollectionName() string

type Session

type Session struct {
	fositeopenid.DefaultSession

	CollectionId string `json:"collection,omitempty"`
}

func NewSession

func NewSession(app core.App, recordId string, collectionId string) *Session

NewSession is a helper function for creating a new session. This may look like a lot of code but since we are setting up multiple strategies it is a bit longer. Usually, you could do:

session = new(fosite.DefaultSession)

func (*Session) Clone

func (s *Session) Clone() fosite.Session

func (*Session) GetJWTClaims

func (s *Session) GetJWTClaims() jwt.JWTClaimsContainer

type SessionModel

type SessionModel interface {
	core.RecordProxy

	GetCollectionName() string
}

type UserInfoAddressClaim

type UserInfoAddressClaim struct {
	// Formatted
	// Full mailing address, formatted for display or use on a mailing label. This field MAY
	// contain multiple lines, separated by newlines. Newlines can be represented either as a
	// carriage return/line feed pair ("\r\n") or as a single line feed character ("\n").
	Formatted string `json:"formatted,omitempty"`

	// Street Address
	// Full street address component, which MAY include house number, street name, Post Office Box,
	// and multi-line extended street address information. This field MAY contain multiple lines,
	// separated by newlines. Newlines can be represented either as a carriage return/line feed
	// pair ("\r\n") or as a single line feed character ("\n").
	StreetAddress string `json:"street_address,omitempty"`

	// Locality
	// City or locality component.
	Locality string `json:"locality,omitempty"`

	// Region
	// State, province, prefecture, or region component.
	Region string `json:"region,omitempty"`

	// Postal Code
	// Zip code or postal code component.
	PostalCode string `json:"postal_code,omitempty"`

	// Country
	// Country name component.
	Country string `json:"country,omitempty"`
}

func (UserInfoAddressClaim) IsEmpty

func (a UserInfoAddressClaim) IsEmpty() bool

type UserInfoClaimStrategy

type UserInfoClaimStrategy interface {
	GetUserInfoClaims(e *core.RequestEvent, scopes []string) (interface{}, error)
}

UserInfoClaimStrategy defines the interface for retrieving user info claims based on the request event and scopes. This allows for custom implementations to determine how user info claims are populated and returned in the /userinfo endpoint.

type UserInfoClaims

type UserInfoClaims struct {
	// Subject
	// Identifier for the End-User at the Issuer.
	Sub string `json:"sub"`

	// Name
	// End-User's full name in displayable form including all name parts,
	// possibly including titles and suffixes, ordered according to the
	// End-User's locale and preferences.
	Name string `json:"name,omitempty"`

	// Given Name
	// Given name(s) or first name(s) of the End-User. Note that in some
	// cultures, people can have multiple given names; all can be present,
	// with the names being separated by space characters.
	GivenName string `json:"given_name,omitempty"`

	// Family Name
	// Surname(s) or last name(s) of the End-User. Note that in some
	// cultures, people can have multiple family names or no family name;
	// all can be present, with the names being separated by space
	// characters.
	FamilyName string `json:"family_name,omitempty"`

	// Middle Name
	// Middle name(s) of the End-User. Note that in some cultures, people
	// can have multiple middle names; all can be present, with the names
	// being separated by space characters.
	MiddleName string `json:"middle_name,omitempty"`

	// Nickname
	// Casual name of the End-User that may or may not be the same as the
	// given_name. For instance, a nickname value of Mike might be returned
	// alongside a given_name value of Michael.
	Nickname string `json:"nickname,omitempty"`

	// Preferred Username
	// Shorthand name by which the End-User wishes to be referred to at the
	// RP, such as janedoe or j.doe. This value MAY be any valid JSON string
	// including special characters such as @, /, or whitespace. The RP MUST
	// NOT rely upon this value being unique, as discussed in Section 5.7.
	PreferredUsername string `json:"preferred_username,omitempty"`

	// Profile
	// URL of the End-User's profile page. The contents of this Web page SHOULD
	// be about the End-User.
	Profile string `json:"profile,omitempty"`

	// Picture
	// URL of the End-User's profile picture. This URL MUST refer to an image
	// file (for example, a PNG, JPEG, or GIF image file), rather than to a
	// Web page containing an image. Note that this URL SHOULD specifically
	// reference a profile photo of the End-User suitable for displaying when
	// describing the End-User, rather than an arbitrary photo taken by the End-User.
	Picture string `json:"picture,omitempty"`

	// Website
	// URL of the End-User's Web page or blog. This Web page SHOULD contain
	// information published by the End-User or an organization that the End-User
	// is affiliated with.
	Website string `json:"website,omitempty"`

	// Email
	// End-User's preferred e-mail address. Its value MUST conform to the RFC 5322
	// addr-spec syntax. The RP MUST NOT rely upon this value being unique, as
	// discussed in Section 5.7.
	Email string `json:"email,omitempty"`

	// Email Verified
	// True if the End-User's e-mail address has been verified; otherwise false.
	// When this Claim Value is true, this means that the OP took affirmative steps
	// to ensure that this e-mail address was controlled by the End-User at the time
	// the verification was performed. The means by which an e-mail address is
	// verified is context specific, and dependent upon the trust framework or
	// contractual agreements within which the parties are operating.
	EmailVerified bool `json:"email_verified,omitempty"`

	// Gender
	// End-User's gender. Values defined by this specification are female and male.
	// Other values MAY be used when neither of the defined values are applicable.
	Gender string `json:"gender,omitempty"`

	// Birthdate
	// End-User's birthday, represented as an ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format.
	// The year MAY be 0000, indicating that it is omitted. To represent only the year,
	// YYYY format is allowed. Note that depending on the underlying platform's date
	// elated function, providing just year can result in varying month and day, so the
	// implementers need to take this factor into account to correctly process the dates.
	Birthdate string `json:"birthdate,omitempty"`

	// ZoneInfo
	// String from IANA Time Zone Database [IANA.time‑zones] representing the End-User's
	// time zone. For example, Europe/Paris or America/Los_Angeles.
	ZoneInfo string `json:"zoneinfo,omitempty"`

	// Locale
	// End-User's locale, represented as a BCP47 [RFC5646] language tag. This is typically
	// an ISO 639 Alpha-2 [ISO639] language code in lowercase and an ISO 3166-1 Alpha-2
	// [ISO3166‑1] country code in uppercase, separated by a dash. For example, en-US or
	// fr-CA. As a compatibility note, some implementations have used an underscore as
	// the separator rather than a dash, for example, en_US; Relying Parties MAY choose
	// to accept this locale syntax as well.
	Locale string `json:"locale,omitempty"`

	// Phone Number
	// End-User's preferred telephone number. E.164 [E.164] is RECOMMENDED as the format of
	// this Claim, for example, +1 (425) 555-1212 or +56 (2) 687 2400. If the phone number
	// contains an extension, it is RECOMMENDED that the extension be represented using the
	// RFC 3966 [RFC3966] extension syntax, for example, +1 (604) 555-1234;ext=5678.
	PhoneNumber string `json:"phone_number,omitempty"`

	// Phone Number Verified
	// True if the End-User's phone number has been verified; otherwise false. When this Claim
	// Value is true, this means that the OP took affirmative steps to ensure that this phone
	// number was controlled by the End-User at the time the verification was performed. The
	// means by which a phone number is verified is context specific, and dependent upon the
	// trust framework or contractual agreements within which the parties are operating. When
	// true, the phone_number Claim MUST be in E.164 format and any extensions MUST be
	// represented in RFC 3966 format.
	PhoneNumberVerified bool `json:"phone_number_verified,omitempty"`

	// Address
	// End-User's preferred postal address. The value of the address member is a JSON [RFC8259]
	// structure containing some or all of the members defined in Section 5.1.1.
	Address *UserInfoAddressClaim `json:"address,omitempty"`

	// Updated At
	// Time the End-User's information was last updated. Its value is a JSON number representing
	// the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time.
	UpdatedAt int64 `json:"updated_at,omitempty"`
}

Directories

Path Synopsis
examples
base command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL