feat: provider source for oauth-providers and sign-in helpers for social login

- classes.OAuthProvider and classes.OAuthProviderSource; GET /oauth-providers
  looks the source up per request and keeps the empty body without one
- exported RegistrationSettings, RegistrationsFromIP, RefreshTTL, RemoteIP
- RegisterOptions.PasswordLess (has_self_set_password=false) and FinishLogin
  (restore + reactivate mail, last_ip_address, last_seen; no event)
- TestOAuthProvidersSourceSmoke, TestSocialHooksSmoke; README
This commit is contained in:
Jakub Zych
2026-10-20 23:02:37 +02:00
parent 1fc0ce7ed0
commit 78a867bccb
6 changed files with 294 additions and 6 deletions

View File

@@ -0,0 +1,31 @@
package classes
import "context"
// OAuthProvider is one social sign-in provider as GET
// /_user/api/v1/oauth-providers lists it: Name is the route segment
// (/oauth/{name}) and Label the button text.
type OAuthProvider struct {
Name string `json:"name"`
Label string `json:"label"`
}
// OAuthProviderSource is what a social-login plugin publishes so the user
// plugin can list its providers and accept them in the unlink routes. The
// user plugin looks it up on every request, so a plugin that boots later is
// still found.
//
// Publish it with an explicit type argument,
//
// app.Publish[classes.OAuthProviderSource](src)
//
// because a bare app.Publish(src) keys the service on its concrete type and
// the lookup misses it (the list then stays empty).
type OAuthProviderSource interface {
// EnabledOAuthProviders returns the providers that are configured right
// now, in display order.
EnabledOAuthProviders(ctx context.Context) []OAuthProvider
// KnownOAuthProviders returns the name of every registered provider,
// enabled or not: an identity of any of them may be unlinked.
KnownOAuthProviders() []string
}