Email and OAuth2
Where Settings Are Stored
Section titled “Where Settings Are Stored”Email login and OAuth2 providers use runtime settings. Email uses the email group, and OAuth2 providers use oauth2.providers.
Email configuration
Section titled “Email configuration”Email settings are stored in PostgreSQL and hot-reloaded across cluster nodes:
synctv settings update \ --set email.smtpHost=smtp.example.com \ --set email.smtpPort=465 \ --set 'email.smtpProxy={"url":"socks5://proxy.example.com:1080"}' \ --set email.useTls=true \ --set email.fromName=SyncTV \ --set email.enabled=true| Field | Default | Meaning |
|---|---|---|
email.enabled | false | Enable email delivery |
email.smtpHost | null | SMTP server host |
email.smtpPort | 587 | SMTP port |
email.smtpCredentials | null | Optional SMTP credentials {username, password} |
email.smtpProxy | null | Optional SOCKS5 proxy {url, credentials?} |
email.fromEmail | null | Sender email address; required and validated when email is enabled |
email.fromName | SyncTV | Sender display name |
email.useTls | true | Whether SMTP uses TLS |
updateMask identifies the fields to replace. To clear smtpHost, fromEmail, smtpCredentials, or smtpProxy, keep its path in updateMask and omit the field from settings.email. Management reads return usernames and the proxy URL while omitting passwords. Omitting password preserves it when the username is unchanged; new credentials and username changes require a password. The proxy resolves the SMTP target hostname. 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. Email signup and review policy live in 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 URLs and Secrets
Section titled “Redirect URLs and Secrets”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.