settings

package
v0.64.0 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package settings is each user's own GitHub/Forgejo credentials — saved through the Settings page, encrypted at rest, and what dashboard.Manager builds that user's forge sources from. Replaces v1's GITHUB_TOKEN/FORGEJO_* environment variables, which configured one dashboard for everyone rather than one per signed-in user.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoEncryptionKey = errors.New("settings: ENCRYPTION_KEY must decode to 32 bytes")

ErrNoEncryptionKey is returned by NewCipher when key isn't valid AES-256 key material — a service holding real credentials has to fail loudly at startup rather than silently store them in the clear.

View Source
var ErrNotFound = errors.New("settings: not found")

ErrNotFound is returned when a user has never saved any credentials.

Functions

func WebhookDeliveryKey added in v0.53.0

func WebhookDeliveryKey(forge, repoFullName string) string

WebhookDeliveryKey is how a repo's forge and full name combine into the key WebhookDeliveries' returned set uses — exported so a caller never has to know or reproduce the separator itself.

Types

type Cipher

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

Cipher encrypts and decrypts credential fields with AES-256-GCM.

func NewCipher

func NewCipher(base64Key string) (*Cipher, error)

NewCipher builds a Cipher from base64Key, the raw form of ENCRYPTION_KEY. Generate one with `openssl rand -base64 32`.

func (*Cipher) Decrypt

func (c *Cipher) Decrypt(encoded string) (string, error)

Decrypt reverses Encrypt. An empty input decrypts to an empty string.

func (*Cipher) Encrypt

func (c *Cipher) Encrypt(plaintext string) (string, error)

Encrypt returns plaintext sealed under a fresh random nonce, both base64-encoded together so Decrypt needs nothing else to reverse it. An empty plaintext encrypts to an empty string — an unset credential field stays unset rather than becoming a real ciphertext of nothing.

type Credentials

type Credentials struct {
	GitHubToken     string
	GitHubUsername  string
	ForgejoURL      string
	ForgejoToken    string
	ForgejoUsername string
	// WebhookToken identifies this user in a webhook URL
	// (/api/webhooks/{provider}/{token}); WebhookSecret is what's pasted
	// into the forge's own webhook "Secret" field and never appears in
	// the URL, so a leaked log line alone can't forge a valid signature.
	// Neither is a third-party credential the way the forge tokens above
	// are, so neither is encrypted at rest — see EnsureWebhookCredentials.
	WebhookToken  string
	WebhookSecret string
	UpdatedAt     time.Time
}

Credentials is one user's forge configuration, decrypted and ready to use — never itself serialized back to a client once saved; see internal/api's settings handlers for what does reach the browser.

type Store

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

Store persists Credentials, encrypted at rest, one row per user.

func NewStore

func NewStore(db *sql.DB, cipher *Cipher) *Store

NewStore wraps db, encrypting and decrypting every token field through cipher. Init must be called once before any other method.

func (*Store) Delete added in v0.9.0

func (s *Store) Delete(ctx context.Context, userID []byte) error

Delete removes userID's saved credentials — a no-op, not an error, if they never saved any. Used when an admin removes the account outright. Also removes their recorded webhook deliveries, the same store's other table.

func (*Store) EnsureWebhookCredentials added in v0.24.0

func (s *Store) EnsureWebhookCredentials(ctx context.Context, userID []byte) (token, secret string, err error)

EnsureWebhookCredentials returns userID's webhook token and secret, generating and persisting them on first call — a user who never opens Settings never gets a row touched for this, and a repeat call always returns the same values (a webhook already configured on a forge points at a URL built from the token; it can't change underneath it). Doesn't touch any other field, including on a user who has no saved row at all yet.

func (*Store) FindByWebhookToken added in v0.25.0

func (s *Store) FindByWebhookToken(ctx context.Context, token string) (userID []byte, secret string, err error)

FindByWebhookToken looks up which user a webhook token belongs to and their signing secret, for verifying an inbound webhook delivery. Returns ErrNotFound for any token with no match — including the empty string, which every row that's never called EnsureWebhookCredentials shares as its default, and which would otherwise resolve to whichever of them the query happened to return first.

func (*Store) Get

func (s *Store) Get(ctx context.Context, userID []byte) (Credentials, error)

Get returns ErrNotFound when userID has never saved any credentials.

func (*Store) Init

func (s *Store) Init(ctx context.Context) error

Init creates the schema if it doesn't already exist. Safe to call every startup.

func (*Store) RecordWebhookDelivery added in v0.53.0

func (s *Store) RecordWebhookDelivery(ctx context.Context, userID []byte, forge, repoFullName string) error

RecordWebhookDelivery notes that userID's webhook for forge/repoFullName just delivered a signature-verified event — the passive signal WebhookDeliveries reports back as "this repo has a working webhook," since actually asking GitHub/Forgejo whether one's configured would need a broader token scope than this app otherwise asks for (see the issue this shipped against for why). Safe to call repeatedly; only the latest timestamp is kept.

func (*Store) Set

func (s *Store) Set(ctx context.Context, userID []byte, c Credentials) error

Set replaces userID's entire credential row — a Settings save is always a full form submit, not a partial patch.

func (*Store) WebhookDeliveries added in v0.53.0

func (s *Store) WebhookDeliveries(ctx context.Context, userID []byte) (map[string]struct{}, error)

WebhookDeliveries returns the set of forge/repo pairs (keyed by WebhookDeliveryKey) that have ever delivered a signature-verified webhook event for userID — empty for a user none of whose repos have, never an error for that case.

Jump to

Keyboard shortcuts

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