Email and OAuth2
Login-related configuration has two parts:
- static email configuration
- runtime OAuth2 provider configuration
OAuth2 providers live in runtime settings under oauth2.providers.
Email configuration
Section titled “Email configuration”Email settings remain static and are used for SMTP connectivity and sender identity.
email: smtp_host: "smtp.example.com" smtp_port: 587 smtp_username: "synctv@example.com" smtp_password_file: "/run/secrets/smtp_password" from_email: "synctv@example.com" from_name: "SyncTV" use_tls: true| Field | Default | Meaning |
|---|---|---|
email.smtp_host | "" | SMTP server host. Empty means email sending is not configured |
email.smtp_port | 587 | SMTP port |
email.smtp_username | "" | SMTP login username |
email.smtp_password | "" | SMTP login password; supports smtp_password_file |
email.from_email | "" | Sender email address. Required and validated when SMTP is configured |
email.from_name | SyncTV | Sender display name |
email.use_tls | true | Whether SMTP uses TLS |
Email verification codes, password reset, and email MFA depend on these SMTP settings. Standalone email login only serves existing accounts; the code request API intentionally returns a generic message to avoid account enumeration. Whether email signup is open or requires review is a runtime setting; see Runtime Settings.
OAuth2 runtime configuration
Section titled “OAuth2 runtime configuration”oauth2.providers is an array of OAuth2ProviderSettings objects. Each element has an instanceName such as github, logto1, or corp_oidc. Instance names may contain only ASCII letters, digits, _, and -.
Every instance uses shared fields plus one provider oneof field:
{ "instanceName": "github", "enableSignup": true, "signupNeedReview": false, "github": { "clientId": "github-client-id", "clientSecret": "github-client-secret", "redirectUrl": "https://app.example.com/oauth2/callback" }}Fields:
| Field | Meaning |
|---|---|
instanceName | Provider instance name |
enableSignup | Whether first-time login through this provider can create a local account |
signupNeedReview | Whether first-time signup should enter the review queue |
| provider oneof field | For example github, google, logto, oidc, or casdoor. Provider-private fields live inside that object |
Common examples
Section titled “Common examples”[ { "instanceName": "github", "enableSignup": true, "signupNeedReview": false, "github": { "clientId": "github-client-id", "clientSecret": "github-client-secret", "redirectUrl": "https://app.example.com/oauth2/callback" } }][ { "instanceName": "corp_oidc", "enableSignup": false, "signupNeedReview": false, "oidc": { "clientId": "synctv", "clientSecret": "oidc-client-secret", "issuer": "https://idp.example.com", "redirectUrl": "https://app.example.com/oauth2/callback" } }]By default, SyncTV uses the issuer for OIDC discovery. Only configure authUrl, tokenUrl, and jwksUrl manually when the IdP does not expose a standard discovery document; userinfoUrl is optional, and verified ID Token claims are used when it is absent.
Runtime behavior
Section titled “Runtime behavior”- When runtime settings change, the OAuth2 service rebuilds its provider map from the new value.
- Missing instance names mean the login entry point is unavailable.
enableSignup=falseonly blocks first-time account creation through that provider. Existing linked OAuth2 logins still work.signupNeedReview=truesends first-time OAuth2 signup into the review flow.
Redirect URL
Section titled “Redirect URL”Each provider instance owns its full callback URL through redirectUrl. Different providers can use their own callback path and scheme.
Where should clientSecret go
Section titled “Where should clientSecret go”Put it in clientSecret and manage it through runtime settings.