Documentation
¶
Overview ¶
Package appleid keeps the link between a Rivolt account and its Sign in with Apple identity (App Store 4.8; architect's design, DA-approved Oct 24): the identity's stable `sub`, which Apple's server-to-server notifications use to name the user, and the refresh token, kept only so deleting the account can revoke it.
The `sub` is in apple_identities; the refresh token is sealed in user_secrets ("apple.refresh_token") like the Rivian session. Neither is ever logged.
Index ¶
- Constants
- Variables
- type Claims
- type Event
- type Mailer
- type NotificationStore
- type Notifier
- type SessionRevoker
- type Store
- func (s *Store) DeliverableEmail(ctx context.Context, userID uuid.UUID) (string, error)
- func (s *Store) DropToken(ctx context.Context, userID uuid.UUID) error
- func (s *Store) Link(ctx context.Context, userID uuid.UUID, sub, refreshToken string) error
- func (s *Store) MarkSeen(ctx context.Context, hash []byte) (bool, error)
- func (s *Store) PurgeSeen(ctx context.Context) (int64, error)
- func (s *Store) RefreshToken(ctx context.Context, userID uuid.UUID) (string, error)
- func (s *Store) SetEmailUndeliverable(ctx context.Context, userID uuid.UUID, v bool) error
- func (s *Store) Unsee(ctx context.Context, hash []byte) error
- func (s *Store) UserBySub(ctx context.Context, sub string) (uuid.UUID, bool, error)
- func (s *Store) UsernameBySub(ctx context.Context, sub string) (string, bool, error)
- type Verifier
Constants ¶
const ( EventConsentRevoked = "consent-revoked" EventAccountDelete = "account-delete" EventEmailDisabled = "email-disabled" EventEmailEnabled = "email-enabled" )
Event types in the `events` claim.
const MaxNotificationBody = 16 << 10
MaxNotificationBody caps the request body (a real notification is about 1 KB).
const NotificationFreshness = time.Hour
NotificationFreshness is how old a notification's `iat` may be.
const SecretName = "apple.refresh_token"
SecretName is the user_secrets entry holding Apple's refresh token for a user.
Variables ¶
var ErrSubInUse = errors.New("appleid: this Apple identity belongs to another account")
ErrSubInUse is returned when an Apple identity is already linked to a different account.
Functions ¶
This section is empty.
Types ¶
type NotificationStore ¶
type NotificationStore interface {
UserBySub(ctx context.Context, sub string) (uuid.UUID, bool, error)
DropToken(ctx context.Context, userID uuid.UUID) error
MarkSeen(ctx context.Context, hash []byte) (bool, error)
Unsee(ctx context.Context, hash []byte) error
SetEmailUndeliverable(ctx context.Context, userID uuid.UUID, v bool) error
DeliverableEmail(ctx context.Context, userID uuid.UUID) (string, error)
}
NotificationStore is the part of Store the endpoint uses.
type Notifier ¶
type Notifier struct {
Verify Verifier
Store NotificationStore
Sessions SessionRevoker
Mail Mailer // nil: no email is sent
Logger *slog.Logger
Now func() time.Time
}
Notifier serves the notifications endpoint. Wrap it with a body cap and a rate limit where it is mounted.
type SessionRevoker ¶
SessionRevoker signs a user out everywhere (sessions.Store).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store links accounts to Apple identities. It works on the system pool (sign-in and Apple's notifications run before or outside a user's request scope).
func (*Store) DeliverableEmail ¶
DeliverableEmail is the account's verified address, or "" if it has none or it is marked undeliverable.
func (*Store) DropToken ¶
DropToken forgets the account's Apple refresh token (consent revoked, or revoked at deletion). The link stays.
func (*Store) Link ¶
Link records that userID signs in with the Apple identity sub, and keeps refreshToken (when Apple issued one) for revocation. Linking the same account again is fine (the token is replaced); a sub already linked to another account is ErrSubInUse, and an account already linked to another sub keeps its first link.
func (*Store) RefreshToken ¶
RefreshToken returns the account's kept Apple refresh token, or "" when there is none.
func (*Store) SetEmailUndeliverable ¶
SetEmailUndeliverable marks (or clears) the account's address as not reachable, for non-essential mail.
type Verifier ¶
Verifier checks a notification JWT's signature, issuer and audience and returns its claims.
func NewVerifier ¶
NewVerifier verifies against keys at issuer+"/auth/keys" (cached, refetched on an unknown key id) for the Services ID clientID. Apple's notifications carry an `exp` that we don't rely on: freshness is the `iat` rule.