Module: Persona

Defined in:
lib/persona.rb,
lib/persona/oidc.rb,
lib/persona/version.rb,
lib/persona/claim_code.rb,
lib/persona/account_link.rb,
lib/persona/oidc/verifier.rb,
lib/persona/oidc/link_store.rb

Overview

Persona — the app-agnostic core of the "anonymous identity you carry per browser" mechanism. The protocol itself is specified in docs/spec; this gem is one adapter around it.

The identity records themselves (agent_uid -> user resolution, guest creation, bindings, recovery codes, merge) live on the consumer's models. This gem owns the seams where app-specific concerns plug in:

- on_join                  domain side effects to run when a browser joins
- guest_nickname_generator what a fresh guest is named when none is given
- guest_email_factory      the placeholder identifier stored on a new guest
- oidc_providers           registered identity providers (see oidc.rb)
- account_link_store       the AccountLink storage port (see account_link.rb)
- link_store               the OIDC round-trip store (see oidc/link_store.rb)
- AGENT_ID_HEADER / AGENT_ID_PARAM / NOT_JOINED_CODE  the wire protocol

Consumer wiring examples live in examples/ at the repository root.

Defined Under Namespace

Modules: AccountLink, ClaimCode, Oidc Classes: Config, ConfigurationError

Constant Summary collapse

AGENT_ID_HEADER =

HTTP header and WebSocket query param (for transports that can't set custom headers) that carry the browser-generated agent_uid. The value itself is never echoed back in responses — docs/spec P-3 / H-3.

'X-Agent-Id'.freeze
AGENT_ID_PARAM =
'agent_id'.freeze
NOT_JOINED_CODE =

Error code returned when a write is attempted by a visitor who hasn't opted in yet; the client reacts by starting the join handshake and retrying. How the code travels (GraphQL extension, HTTP status + body, HTML fragment) is transport-specific — the name is the protocol.

'NOT_JOINED'.freeze
NICKNAME_ADJECTIVES =

Default guest-nickname vocabulary: adjective-noun-hex, readable and collision-resistant enough for a display handle. Consumers can replace the whole generator via Persona.config.guest_nickname_generator.

%w[
  azure crimson emerald golden silver violet amber coral indigo jade
  onyx pearl ruby sapphire topaz cobalt scarlet teal magenta saffron
].freeze
NICKNAME_NOUNS =
%w[
  otter falcon mantis lynx ibis pangolin heron badger marmot newt
  raven sparrow tapir gecko axolotl puffin lemur kestrel quokka tern
].freeze
FALSEY_ENV_VALUES =

Env values treated as "off" for feature flags, mirroring the usual Rails-style boolean casting so consumers coming from ActiveModel see no behavior change. Anything else non-empty counts as "on".

%w[0 f F false FALSE off OFF].freeze
VERSION =
'0.1.0'.freeze

Class Method Summary collapse

Class Method Details

.account_linking_enabled?Boolean

Account linking (OIDC binding to an external IdP) is opt-in and off by default — until it is enabled, no /auth/oidc routes or link mutations do anything. Toggled by the PERSONA_ACCOUNT_LINKING env var.

Returns:

  • (Boolean)


140
141
142
143
144
145
# File 'lib/persona.rb', line 140

def 
  value = ENV.fetch('PERSONA_ACCOUNT_LINKING', nil)
  return false if value.nil? || value.empty?

  !FALSEY_ENV_VALUES.include?(value)
end

.configObject



111
112
113
# File 'lib/persona.rb', line 111

def config
  @config ||= Config.new
end

.configure {|config| ... } ⇒ Object

Yields:



115
116
117
# File 'lib/persona.rb', line 115

def configure
  yield config
end

.generate_nicknameObject



124
125
126
# File 'lib/persona.rb', line 124

def generate_nickname
  "#{NICKNAME_ADJECTIVES.sample}-#{NICKNAME_NOUNS.sample}-#{SecureRandom.hex(2)}"
end

.oidc_provider(name) ⇒ Object

Resolves a registered OIDC provider by name; unknown names raise so a begin/callback for a provider the app never registered fails loudly.



130
131
132
133
134
135
# File 'lib/persona.rb', line 130

def oidc_provider(name)
  config.oidc_providers.fetch(name) do
    raise ConfigurationError, "unknown OIDC provider #{name.inspect}" \
                              'register it via Persona.config.register_oidc_provider'
  end
end

.reset_config!Object

Discards all wiring and returns to defaults. Intended for test suites.



120
121
122
# File 'lib/persona.rb', line 120

def reset_config!
  @config = Config.new
end