options.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package config // import "miniflux.app/v2/internal/config"
  4. import (
  5. "fmt"
  6. "net/url"
  7. "sort"
  8. "strings"
  9. "time"
  10. "miniflux.app/v2/internal/crypto"
  11. "miniflux.app/v2/internal/version"
  12. )
  13. const (
  14. defaultHTTPS = false
  15. defaultLogFile = "stderr"
  16. defaultLogDateTime = false
  17. defaultLogFormat = "text"
  18. defaultLogLevel = "info"
  19. defaultHSTS = true
  20. defaultHTTPService = true
  21. defaultSchedulerService = true
  22. defaultBaseURL = "http://localhost"
  23. defaultRootURL = "http://localhost"
  24. defaultBasePath = ""
  25. defaultWorkerPoolSize = 16
  26. defaultPollingFrequency = 60
  27. defaultForceRefreshInterval = 30
  28. defaultBatchSize = 100
  29. defaultPollingScheduler = "round_robin"
  30. defaultSchedulerEntryFrequencyMinInterval = 5
  31. defaultSchedulerEntryFrequencyMaxInterval = 24 * 60
  32. defaultSchedulerEntryFrequencyFactor = 1
  33. defaultSchedulerRoundRobinMinInterval = 60
  34. defaultSchedulerRoundRobinMaxInterval = 1440
  35. defaultPollingParsingErrorLimit = 3
  36. defaultRunMigrations = false
  37. defaultDatabaseURL = "user=postgres password=postgres dbname=miniflux2 sslmode=disable"
  38. defaultDatabaseMaxConns = 20
  39. defaultDatabaseMinConns = 1
  40. defaultDatabaseConnectionLifetime = 5
  41. defaultListenAddr = "127.0.0.1:8080"
  42. defaultCertFile = ""
  43. defaultKeyFile = ""
  44. defaultCertDomain = ""
  45. defaultCleanupFrequencyHours = 24
  46. defaultCleanupArchiveReadDays = 60
  47. defaultCleanupArchiveUnreadDays = 180
  48. defaultCleanupArchiveBatchSize = 10000
  49. defaultCleanupRemoveSessionsDays = 30
  50. defaultMediaProxyHTTPClientTimeout = 120
  51. defaultMediaProxyMode = "http-only"
  52. defaultMediaResourceTypes = "image"
  53. defaultMediaProxyURL = ""
  54. defaultFilterEntryMaxAgeDays = 0
  55. defaultFetchBilibiliWatchTime = false
  56. defaultFetchNebulaWatchTime = false
  57. defaultFetchOdyseeWatchTime = false
  58. defaultFetchYouTubeWatchTime = false
  59. defaultYouTubeApiKey = ""
  60. defaultYouTubeEmbedUrlOverride = "https://www.youtube-nocookie.com/embed/"
  61. defaultCreateAdmin = false
  62. defaultAdminUsername = ""
  63. defaultAdminPassword = ""
  64. defaultOAuth2UserCreation = false
  65. defaultOAuth2ClientID = ""
  66. defaultOAuth2ClientSecret = ""
  67. defaultOAuth2RedirectURL = ""
  68. defaultOAuth2OidcDiscoveryEndpoint = ""
  69. defaultOauth2OidcProviderName = "OpenID Connect"
  70. defaultOAuth2Provider = ""
  71. defaultDisableLocalAuth = false
  72. defaultHTTPClientTimeout = 20
  73. defaultHTTPClientMaxBodySize = 15
  74. defaultHTTPClientProxy = ""
  75. defaultHTTPServerTimeout = 300
  76. defaultAuthProxyHeader = ""
  77. defaultAuthProxyUserCreation = false
  78. defaultMaintenanceMode = false
  79. defaultMaintenanceMessage = "Miniflux is currently under maintenance"
  80. defaultMetricsCollector = false
  81. defaultMetricsRefreshInterval = 60
  82. defaultMetricsAllowedNetworks = "127.0.0.1/8"
  83. defaultMetricsUsername = ""
  84. defaultMetricsPassword = ""
  85. defaultWatchdog = true
  86. defaultInvidiousInstance = "yewtu.be"
  87. defaultWebAuthn = false
  88. )
  89. var defaultHTTPClientUserAgent = "Mozilla/5.0 (compatible; Miniflux/" + version.Version + "; +https://miniflux.app)"
  90. // Option contains a key to value map of a single option. It may be used to output debug strings.
  91. type Option struct {
  92. Key string
  93. Value interface{}
  94. }
  95. // Options contains configuration options.
  96. type Options struct {
  97. HTTPS bool
  98. logFile string
  99. logDateTime bool
  100. logFormat string
  101. logLevel string
  102. hsts bool
  103. httpService bool
  104. schedulerService bool
  105. baseURL string
  106. rootURL string
  107. basePath string
  108. databaseURL string
  109. databaseMaxConns int
  110. databaseMinConns int
  111. databaseConnectionLifetime int
  112. runMigrations bool
  113. listenAddr []string
  114. certFile string
  115. certDomain string
  116. certKeyFile string
  117. cleanupFrequencyHours int
  118. cleanupArchiveReadDays int
  119. cleanupArchiveUnreadDays int
  120. cleanupArchiveBatchSize int
  121. cleanupRemoveSessionsDays int
  122. pollingFrequency int
  123. forceRefreshInterval int
  124. batchSize int
  125. pollingScheduler string
  126. schedulerEntryFrequencyMinInterval int
  127. schedulerEntryFrequencyMaxInterval int
  128. schedulerEntryFrequencyFactor int
  129. schedulerRoundRobinMinInterval int
  130. schedulerRoundRobinMaxInterval int
  131. pollingParsingErrorLimit int
  132. workerPoolSize int
  133. createAdmin bool
  134. adminUsername string
  135. adminPassword string
  136. mediaProxyHTTPClientTimeout int
  137. mediaProxyMode string
  138. mediaProxyResourceTypes []string
  139. mediaProxyCustomURL string
  140. fetchBilibiliWatchTime bool
  141. fetchNebulaWatchTime bool
  142. fetchOdyseeWatchTime bool
  143. fetchYouTubeWatchTime bool
  144. filterEntryMaxAgeDays int
  145. youTubeApiKey string
  146. youTubeEmbedUrlOverride string
  147. youTubeEmbedDomain string
  148. oauth2UserCreationAllowed bool
  149. oauth2ClientID string
  150. oauth2ClientSecret string
  151. oauth2RedirectURL string
  152. oidcDiscoveryEndpoint string
  153. oidcProviderName string
  154. oauth2Provider string
  155. disableLocalAuth bool
  156. httpClientTimeout int
  157. httpClientMaxBodySize int64
  158. httpClientProxyURL *url.URL
  159. httpClientProxies []string
  160. httpClientUserAgent string
  161. httpServerTimeout int
  162. authProxyHeader string
  163. authProxyUserCreation bool
  164. maintenanceMode bool
  165. maintenanceMessage string
  166. metricsCollector bool
  167. metricsRefreshInterval int
  168. metricsAllowedNetworks []string
  169. metricsUsername string
  170. metricsPassword string
  171. watchdog bool
  172. invidiousInstance string
  173. mediaProxyPrivateKey []byte
  174. webAuthn bool
  175. }
  176. // NewOptions returns Options with default values.
  177. func NewOptions() *Options {
  178. return &Options{
  179. HTTPS: defaultHTTPS,
  180. logFile: defaultLogFile,
  181. logDateTime: defaultLogDateTime,
  182. logFormat: defaultLogFormat,
  183. logLevel: defaultLogLevel,
  184. hsts: defaultHSTS,
  185. httpService: defaultHTTPService,
  186. schedulerService: defaultSchedulerService,
  187. baseURL: defaultBaseURL,
  188. rootURL: defaultRootURL,
  189. basePath: defaultBasePath,
  190. databaseURL: defaultDatabaseURL,
  191. databaseMaxConns: defaultDatabaseMaxConns,
  192. databaseMinConns: defaultDatabaseMinConns,
  193. databaseConnectionLifetime: defaultDatabaseConnectionLifetime,
  194. runMigrations: defaultRunMigrations,
  195. listenAddr: []string{defaultListenAddr},
  196. certFile: defaultCertFile,
  197. certDomain: defaultCertDomain,
  198. certKeyFile: defaultKeyFile,
  199. cleanupFrequencyHours: defaultCleanupFrequencyHours,
  200. cleanupArchiveReadDays: defaultCleanupArchiveReadDays,
  201. cleanupArchiveUnreadDays: defaultCleanupArchiveUnreadDays,
  202. cleanupArchiveBatchSize: defaultCleanupArchiveBatchSize,
  203. cleanupRemoveSessionsDays: defaultCleanupRemoveSessionsDays,
  204. pollingFrequency: defaultPollingFrequency,
  205. forceRefreshInterval: defaultForceRefreshInterval,
  206. batchSize: defaultBatchSize,
  207. pollingScheduler: defaultPollingScheduler,
  208. schedulerEntryFrequencyMinInterval: defaultSchedulerEntryFrequencyMinInterval,
  209. schedulerEntryFrequencyMaxInterval: defaultSchedulerEntryFrequencyMaxInterval,
  210. schedulerEntryFrequencyFactor: defaultSchedulerEntryFrequencyFactor,
  211. schedulerRoundRobinMinInterval: defaultSchedulerRoundRobinMinInterval,
  212. schedulerRoundRobinMaxInterval: defaultSchedulerRoundRobinMaxInterval,
  213. pollingParsingErrorLimit: defaultPollingParsingErrorLimit,
  214. workerPoolSize: defaultWorkerPoolSize,
  215. createAdmin: defaultCreateAdmin,
  216. mediaProxyHTTPClientTimeout: defaultMediaProxyHTTPClientTimeout,
  217. mediaProxyMode: defaultMediaProxyMode,
  218. mediaProxyResourceTypes: []string{defaultMediaResourceTypes},
  219. mediaProxyCustomURL: defaultMediaProxyURL,
  220. filterEntryMaxAgeDays: defaultFilterEntryMaxAgeDays,
  221. fetchBilibiliWatchTime: defaultFetchBilibiliWatchTime,
  222. fetchNebulaWatchTime: defaultFetchNebulaWatchTime,
  223. fetchOdyseeWatchTime: defaultFetchOdyseeWatchTime,
  224. fetchYouTubeWatchTime: defaultFetchYouTubeWatchTime,
  225. youTubeApiKey: defaultYouTubeApiKey,
  226. youTubeEmbedUrlOverride: defaultYouTubeEmbedUrlOverride,
  227. oauth2UserCreationAllowed: defaultOAuth2UserCreation,
  228. oauth2ClientID: defaultOAuth2ClientID,
  229. oauth2ClientSecret: defaultOAuth2ClientSecret,
  230. oauth2RedirectURL: defaultOAuth2RedirectURL,
  231. oidcDiscoveryEndpoint: defaultOAuth2OidcDiscoveryEndpoint,
  232. oidcProviderName: defaultOauth2OidcProviderName,
  233. oauth2Provider: defaultOAuth2Provider,
  234. disableLocalAuth: defaultDisableLocalAuth,
  235. httpClientTimeout: defaultHTTPClientTimeout,
  236. httpClientMaxBodySize: defaultHTTPClientMaxBodySize * 1024 * 1024,
  237. httpClientProxyURL: nil,
  238. httpClientProxies: []string{},
  239. httpClientUserAgent: defaultHTTPClientUserAgent,
  240. httpServerTimeout: defaultHTTPServerTimeout,
  241. authProxyHeader: defaultAuthProxyHeader,
  242. authProxyUserCreation: defaultAuthProxyUserCreation,
  243. maintenanceMode: defaultMaintenanceMode,
  244. maintenanceMessage: defaultMaintenanceMessage,
  245. metricsCollector: defaultMetricsCollector,
  246. metricsRefreshInterval: defaultMetricsRefreshInterval,
  247. metricsAllowedNetworks: []string{defaultMetricsAllowedNetworks},
  248. metricsUsername: defaultMetricsUsername,
  249. metricsPassword: defaultMetricsPassword,
  250. watchdog: defaultWatchdog,
  251. invidiousInstance: defaultInvidiousInstance,
  252. mediaProxyPrivateKey: crypto.GenerateRandomBytes(16),
  253. webAuthn: defaultWebAuthn,
  254. }
  255. }
  256. func (o *Options) LogFile() string {
  257. return o.logFile
  258. }
  259. // LogDateTime returns true if the date/time should be displayed in log messages.
  260. func (o *Options) LogDateTime() bool {
  261. return o.logDateTime
  262. }
  263. // LogFormat returns the log format.
  264. func (o *Options) LogFormat() string {
  265. return o.logFormat
  266. }
  267. // LogLevel returns the log level.
  268. func (o *Options) LogLevel() string {
  269. return o.logLevel
  270. }
  271. // SetLogLevel sets the log level.
  272. func (o *Options) SetLogLevel(level string) {
  273. o.logLevel = level
  274. }
  275. // HasMaintenanceMode returns true if maintenance mode is enabled.
  276. func (o *Options) HasMaintenanceMode() bool {
  277. return o.maintenanceMode
  278. }
  279. // MaintenanceMessage returns maintenance message.
  280. func (o *Options) MaintenanceMessage() string {
  281. return o.maintenanceMessage
  282. }
  283. // BaseURL returns the application base URL with path.
  284. func (o *Options) BaseURL() string {
  285. return o.baseURL
  286. }
  287. // RootURL returns the base URL without path.
  288. func (o *Options) RootURL() string {
  289. return o.rootURL
  290. }
  291. // BasePath returns the application base path according to the base URL.
  292. func (o *Options) BasePath() string {
  293. return o.basePath
  294. }
  295. // IsDefaultDatabaseURL returns true if the default database URL is used.
  296. func (o *Options) IsDefaultDatabaseURL() bool {
  297. return o.databaseURL == defaultDatabaseURL
  298. }
  299. // DatabaseURL returns the database URL.
  300. func (o *Options) DatabaseURL() string {
  301. return o.databaseURL
  302. }
  303. // DatabaseMaxConns returns the maximum number of database connections.
  304. func (o *Options) DatabaseMaxConns() int {
  305. return o.databaseMaxConns
  306. }
  307. // DatabaseMinConns returns the minimum number of database connections.
  308. func (o *Options) DatabaseMinConns() int {
  309. return o.databaseMinConns
  310. }
  311. // DatabaseConnectionLifetime returns the maximum amount of time a connection may be reused.
  312. func (o *Options) DatabaseConnectionLifetime() time.Duration {
  313. return time.Duration(o.databaseConnectionLifetime) * time.Minute
  314. }
  315. // ListenAddr returns the listen address for the HTTP server.
  316. func (o *Options) ListenAddr() []string {
  317. return o.listenAddr
  318. }
  319. // CertFile returns the SSL certificate filename if any.
  320. func (o *Options) CertFile() string {
  321. return o.certFile
  322. }
  323. // CertKeyFile returns the private key filename for custom SSL certificate.
  324. func (o *Options) CertKeyFile() string {
  325. return o.certKeyFile
  326. }
  327. // CertDomain returns the domain to use for Let's Encrypt certificate.
  328. func (o *Options) CertDomain() string {
  329. return o.certDomain
  330. }
  331. // CleanupFrequencyHours returns the interval in hours for cleanup jobs.
  332. func (o *Options) CleanupFrequencyHours() int {
  333. return o.cleanupFrequencyHours
  334. }
  335. // CleanupArchiveReadDays returns the number of days after which marking read items as removed.
  336. func (o *Options) CleanupArchiveReadDays() int {
  337. return o.cleanupArchiveReadDays
  338. }
  339. // CleanupArchiveUnreadDays returns the number of days after which marking unread items as removed.
  340. func (o *Options) CleanupArchiveUnreadDays() int {
  341. return o.cleanupArchiveUnreadDays
  342. }
  343. // CleanupArchiveBatchSize returns the number of entries to archive for each interval.
  344. func (o *Options) CleanupArchiveBatchSize() int {
  345. return o.cleanupArchiveBatchSize
  346. }
  347. // CleanupRemoveSessionsDays returns the number of days after which to remove sessions.
  348. func (o *Options) CleanupRemoveSessionsDays() int {
  349. return o.cleanupRemoveSessionsDays
  350. }
  351. // WorkerPoolSize returns the number of background worker.
  352. func (o *Options) WorkerPoolSize() int {
  353. return o.workerPoolSize
  354. }
  355. // PollingFrequency returns the interval to refresh feeds in the background.
  356. func (o *Options) PollingFrequency() int {
  357. return o.pollingFrequency
  358. }
  359. // ForceRefreshInterval returns the force refresh interval
  360. func (o *Options) ForceRefreshInterval() int {
  361. return o.forceRefreshInterval
  362. }
  363. // BatchSize returns the number of feeds to send for background processing.
  364. func (o *Options) BatchSize() int {
  365. return o.batchSize
  366. }
  367. // PollingScheduler returns the scheduler used for polling feeds.
  368. func (o *Options) PollingScheduler() string {
  369. return o.pollingScheduler
  370. }
  371. // SchedulerEntryFrequencyMaxInterval returns the maximum interval in minutes for the entry frequency scheduler.
  372. func (o *Options) SchedulerEntryFrequencyMaxInterval() int {
  373. return o.schedulerEntryFrequencyMaxInterval
  374. }
  375. // SchedulerEntryFrequencyMinInterval returns the minimum interval in minutes for the entry frequency scheduler.
  376. func (o *Options) SchedulerEntryFrequencyMinInterval() int {
  377. return o.schedulerEntryFrequencyMinInterval
  378. }
  379. // SchedulerEntryFrequencyFactor returns the factor for the entry frequency scheduler.
  380. func (o *Options) SchedulerEntryFrequencyFactor() int {
  381. return o.schedulerEntryFrequencyFactor
  382. }
  383. func (o *Options) SchedulerRoundRobinMinInterval() int {
  384. return o.schedulerRoundRobinMinInterval
  385. }
  386. func (o *Options) SchedulerRoundRobinMaxInterval() int {
  387. return o.schedulerRoundRobinMaxInterval
  388. }
  389. // PollingParsingErrorLimit returns the limit of errors when to stop polling.
  390. func (o *Options) PollingParsingErrorLimit() int {
  391. return o.pollingParsingErrorLimit
  392. }
  393. // IsOAuth2UserCreationAllowed returns true if user creation is allowed for OAuth2 users.
  394. func (o *Options) IsOAuth2UserCreationAllowed() bool {
  395. return o.oauth2UserCreationAllowed
  396. }
  397. // OAuth2ClientID returns the OAuth2 Client ID.
  398. func (o *Options) OAuth2ClientID() string {
  399. return o.oauth2ClientID
  400. }
  401. // OAuth2ClientSecret returns the OAuth2 client secret.
  402. func (o *Options) OAuth2ClientSecret() string {
  403. return o.oauth2ClientSecret
  404. }
  405. // OAuth2RedirectURL returns the OAuth2 redirect URL.
  406. func (o *Options) OAuth2RedirectURL() string {
  407. return o.oauth2RedirectURL
  408. }
  409. // OIDCDiscoveryEndpoint returns the OAuth2 OIDC discovery endpoint.
  410. func (o *Options) OIDCDiscoveryEndpoint() string {
  411. return o.oidcDiscoveryEndpoint
  412. }
  413. // OIDCProviderName returns the OAuth2 OIDC provider's display name
  414. func (o *Options) OIDCProviderName() string {
  415. return o.oidcProviderName
  416. }
  417. // OAuth2Provider returns the name of the OAuth2 provider configured.
  418. func (o *Options) OAuth2Provider() string {
  419. return o.oauth2Provider
  420. }
  421. // DisableLocalAUth returns true if the local user database should not be used to authenticate users
  422. func (o *Options) DisableLocalAuth() bool {
  423. return o.disableLocalAuth
  424. }
  425. // HasHSTS returns true if HTTP Strict Transport Security is enabled.
  426. func (o *Options) HasHSTS() bool {
  427. return o.hsts
  428. }
  429. // RunMigrations returns true if the environment variable RUN_MIGRATIONS is not empty.
  430. func (o *Options) RunMigrations() bool {
  431. return o.runMigrations
  432. }
  433. // CreateAdmin returns true if the environment variable CREATE_ADMIN is not empty.
  434. func (o *Options) CreateAdmin() bool {
  435. return o.createAdmin
  436. }
  437. // AdminUsername returns the admin username if defined.
  438. func (o *Options) AdminUsername() string {
  439. return o.adminUsername
  440. }
  441. // AdminPassword returns the admin password if defined.
  442. func (o *Options) AdminPassword() string {
  443. return o.adminPassword
  444. }
  445. // FetchYouTubeWatchTime returns true if the YouTube video duration
  446. // should be fetched and used as a reading time.
  447. func (o *Options) FetchYouTubeWatchTime() bool {
  448. return o.fetchYouTubeWatchTime
  449. }
  450. // YouTubeApiKey returns the YouTube API key if defined.
  451. func (o *Options) YouTubeApiKey() string {
  452. return o.youTubeApiKey
  453. }
  454. // YouTubeEmbedUrlOverride returns the YouTube embed URL override if defined.
  455. func (o *Options) YouTubeEmbedUrlOverride() string {
  456. return o.youTubeEmbedUrlOverride
  457. }
  458. // YouTubeEmbedDomain returns the domain used for YouTube embeds.
  459. func (o *Options) YouTubeEmbedDomain() string {
  460. if o.youTubeEmbedDomain != "" {
  461. return o.youTubeEmbedDomain
  462. }
  463. return "www.youtube-nocookie.com"
  464. }
  465. // FetchNebulaWatchTime returns true if the Nebula video duration
  466. // should be fetched and used as a reading time.
  467. func (o *Options) FetchNebulaWatchTime() bool {
  468. return o.fetchNebulaWatchTime
  469. }
  470. // FetchOdyseeWatchTime returns true if the Odysee video duration
  471. // should be fetched and used as a reading time.
  472. func (o *Options) FetchOdyseeWatchTime() bool {
  473. return o.fetchOdyseeWatchTime
  474. }
  475. // FetchBilibiliWatchTime returns true if the Bilibili video duration
  476. // should be fetched and used as a reading time.
  477. func (o *Options) FetchBilibiliWatchTime() bool {
  478. return o.fetchBilibiliWatchTime
  479. }
  480. // MediaProxyMode returns "none" to never proxy, "http-only" to proxy non-HTTPS, "all" to always proxy.
  481. func (o *Options) MediaProxyMode() string {
  482. return o.mediaProxyMode
  483. }
  484. // MediaProxyResourceTypes returns a slice of resource types to proxy.
  485. func (o *Options) MediaProxyResourceTypes() []string {
  486. return o.mediaProxyResourceTypes
  487. }
  488. // MediaCustomProxyURL returns the custom proxy URL for medias.
  489. func (o *Options) MediaCustomProxyURL() string {
  490. return o.mediaProxyCustomURL
  491. }
  492. // MediaProxyHTTPClientTimeout returns the time limit in seconds before the proxy HTTP client cancel the request.
  493. func (o *Options) MediaProxyHTTPClientTimeout() int {
  494. return o.mediaProxyHTTPClientTimeout
  495. }
  496. // MediaProxyPrivateKey returns the private key used by the media proxy.
  497. func (o *Options) MediaProxyPrivateKey() []byte {
  498. return o.mediaProxyPrivateKey
  499. }
  500. // HasHTTPService returns true if the HTTP service is enabled.
  501. func (o *Options) HasHTTPService() bool {
  502. return o.httpService
  503. }
  504. // HasSchedulerService returns true if the scheduler service is enabled.
  505. func (o *Options) HasSchedulerService() bool {
  506. return o.schedulerService
  507. }
  508. // HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request.
  509. func (o *Options) HTTPClientTimeout() int {
  510. return o.httpClientTimeout
  511. }
  512. // HTTPClientMaxBodySize returns the number of bytes allowed for the HTTP client to transfer.
  513. func (o *Options) HTTPClientMaxBodySize() int64 {
  514. return o.httpClientMaxBodySize
  515. }
  516. // HTTPClientProxyURL returns the client HTTP proxy URL if configured.
  517. func (o *Options) HTTPClientProxyURL() *url.URL {
  518. return o.httpClientProxyURL
  519. }
  520. // HasHTTPClientProxyURLConfigured returns true if the client HTTP proxy URL if configured.
  521. func (o *Options) HasHTTPClientProxyURLConfigured() bool {
  522. return o.httpClientProxyURL != nil
  523. }
  524. // HTTPClientProxies returns the list of proxies.
  525. func (o *Options) HTTPClientProxies() []string {
  526. return o.httpClientProxies
  527. }
  528. // HTTPClientProxiesString returns true if the list of rotating proxies are configured.
  529. func (o *Options) HasHTTPClientProxiesConfigured() bool {
  530. return len(o.httpClientProxies) > 0
  531. }
  532. // HTTPServerTimeout returns the time limit in seconds before the HTTP server cancel the request.
  533. func (o *Options) HTTPServerTimeout() int {
  534. return o.httpServerTimeout
  535. }
  536. // AuthProxyHeader returns an HTTP header name that contains username for
  537. // authentication using auth proxy.
  538. func (o *Options) AuthProxyHeader() string {
  539. return o.authProxyHeader
  540. }
  541. // IsAuthProxyUserCreationAllowed returns true if user creation is allowed for
  542. // users authenticated using auth proxy.
  543. func (o *Options) IsAuthProxyUserCreationAllowed() bool {
  544. return o.authProxyUserCreation
  545. }
  546. // HasMetricsCollector returns true if metrics collection is enabled.
  547. func (o *Options) HasMetricsCollector() bool {
  548. return o.metricsCollector
  549. }
  550. // MetricsRefreshInterval returns the refresh interval in seconds.
  551. func (o *Options) MetricsRefreshInterval() int {
  552. return o.metricsRefreshInterval
  553. }
  554. // MetricsAllowedNetworks returns the list of networks allowed to connect to the metrics endpoint.
  555. func (o *Options) MetricsAllowedNetworks() []string {
  556. return o.metricsAllowedNetworks
  557. }
  558. func (o *Options) MetricsUsername() string {
  559. return o.metricsUsername
  560. }
  561. func (o *Options) MetricsPassword() string {
  562. return o.metricsPassword
  563. }
  564. // HTTPClientUserAgent returns the global User-Agent header for miniflux.
  565. func (o *Options) HTTPClientUserAgent() string {
  566. return o.httpClientUserAgent
  567. }
  568. // HasWatchdog returns true if the systemd watchdog is enabled.
  569. func (o *Options) HasWatchdog() bool {
  570. return o.watchdog
  571. }
  572. // InvidiousInstance returns the invidious instance used by miniflux
  573. func (o *Options) InvidiousInstance() string {
  574. return o.invidiousInstance
  575. }
  576. // WebAuthn returns true if WebAuthn logins are supported
  577. func (o *Options) WebAuthn() bool {
  578. return o.webAuthn
  579. }
  580. // FilterEntryMaxAgeDays returns the number of days after which entries should be retained.
  581. func (o *Options) FilterEntryMaxAgeDays() int {
  582. return o.filterEntryMaxAgeDays
  583. }
  584. // SortedOptions returns options as a list of key value pairs, sorted by keys.
  585. func (o *Options) SortedOptions(redactSecret bool) []*Option {
  586. var clientProxyURLRedacted string
  587. if o.httpClientProxyURL != nil {
  588. if redactSecret {
  589. clientProxyURLRedacted = o.httpClientProxyURL.Redacted()
  590. } else {
  591. clientProxyURLRedacted = o.httpClientProxyURL.String()
  592. }
  593. }
  594. var clientProxyURLsRedacted string
  595. if len(o.httpClientProxies) > 0 {
  596. if redactSecret {
  597. var proxyURLs []string
  598. for range o.httpClientProxies {
  599. proxyURLs = append(proxyURLs, "<redacted>")
  600. }
  601. clientProxyURLsRedacted = strings.Join(proxyURLs, ",")
  602. } else {
  603. clientProxyURLsRedacted = strings.Join(o.httpClientProxies, ",")
  604. }
  605. }
  606. var mediaProxyPrivateKeyValue string
  607. if len(o.mediaProxyPrivateKey) > 0 {
  608. mediaProxyPrivateKeyValue = "<binary-data>"
  609. }
  610. var keyValues = map[string]interface{}{
  611. "ADMIN_PASSWORD": redactSecretValue(o.adminPassword, redactSecret),
  612. "ADMIN_USERNAME": o.adminUsername,
  613. "AUTH_PROXY_HEADER": o.authProxyHeader,
  614. "AUTH_PROXY_USER_CREATION": o.authProxyUserCreation,
  615. "BASE_PATH": o.basePath,
  616. "BASE_URL": o.baseURL,
  617. "BATCH_SIZE": o.batchSize,
  618. "CERT_DOMAIN": o.certDomain,
  619. "CERT_FILE": o.certFile,
  620. "CLEANUP_ARCHIVE_BATCH_SIZE": o.cleanupArchiveBatchSize,
  621. "CLEANUP_ARCHIVE_READ_DAYS": o.cleanupArchiveReadDays,
  622. "CLEANUP_ARCHIVE_UNREAD_DAYS": o.cleanupArchiveUnreadDays,
  623. "CLEANUP_FREQUENCY_HOURS": o.cleanupFrequencyHours,
  624. "CLEANUP_REMOVE_SESSIONS_DAYS": o.cleanupRemoveSessionsDays,
  625. "CREATE_ADMIN": o.createAdmin,
  626. "DATABASE_CONNECTION_LIFETIME": o.databaseConnectionLifetime,
  627. "DATABASE_MAX_CONNS": o.databaseMaxConns,
  628. "DATABASE_MIN_CONNS": o.databaseMinConns,
  629. "DATABASE_URL": redactSecretValue(o.databaseURL, redactSecret),
  630. "DISABLE_HSTS": !o.hsts,
  631. "DISABLE_HTTP_SERVICE": !o.httpService,
  632. "DISABLE_SCHEDULER_SERVICE": !o.schedulerService,
  633. "FILTER_ENTRY_MAX_AGE_DAYS": o.filterEntryMaxAgeDays,
  634. "FETCH_YOUTUBE_WATCH_TIME": o.fetchYouTubeWatchTime,
  635. "FETCH_NEBULA_WATCH_TIME": o.fetchNebulaWatchTime,
  636. "FETCH_ODYSEE_WATCH_TIME": o.fetchOdyseeWatchTime,
  637. "FETCH_BILIBILI_WATCH_TIME": o.fetchBilibiliWatchTime,
  638. "HTTPS": o.HTTPS,
  639. "HTTP_CLIENT_MAX_BODY_SIZE": o.httpClientMaxBodySize,
  640. "HTTP_CLIENT_PROXIES": clientProxyURLsRedacted,
  641. "HTTP_CLIENT_PROXY": clientProxyURLRedacted,
  642. "HTTP_CLIENT_TIMEOUT": o.httpClientTimeout,
  643. "HTTP_CLIENT_USER_AGENT": o.httpClientUserAgent,
  644. "HTTP_SERVER_TIMEOUT": o.httpServerTimeout,
  645. "HTTP_SERVICE": o.httpService,
  646. "INVIDIOUS_INSTANCE": o.invidiousInstance,
  647. "KEY_FILE": o.certKeyFile,
  648. "LISTEN_ADDR": strings.Join(o.listenAddr, ","),
  649. "LOG_FILE": o.logFile,
  650. "LOG_DATE_TIME": o.logDateTime,
  651. "LOG_FORMAT": o.logFormat,
  652. "LOG_LEVEL": o.logLevel,
  653. "MAINTENANCE_MESSAGE": o.maintenanceMessage,
  654. "MAINTENANCE_MODE": o.maintenanceMode,
  655. "METRICS_ALLOWED_NETWORKS": strings.Join(o.metricsAllowedNetworks, ","),
  656. "METRICS_COLLECTOR": o.metricsCollector,
  657. "METRICS_PASSWORD": redactSecretValue(o.metricsPassword, redactSecret),
  658. "METRICS_REFRESH_INTERVAL": o.metricsRefreshInterval,
  659. "METRICS_USERNAME": o.metricsUsername,
  660. "OAUTH2_CLIENT_ID": o.oauth2ClientID,
  661. "OAUTH2_CLIENT_SECRET": redactSecretValue(o.oauth2ClientSecret, redactSecret),
  662. "OAUTH2_OIDC_DISCOVERY_ENDPOINT": o.oidcDiscoveryEndpoint,
  663. "OAUTH2_OIDC_PROVIDER_NAME": o.oidcProviderName,
  664. "OAUTH2_PROVIDER": o.oauth2Provider,
  665. "OAUTH2_REDIRECT_URL": o.oauth2RedirectURL,
  666. "OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
  667. "DISABLE_LOCAL_AUTH": o.disableLocalAuth,
  668. "POLLING_FREQUENCY": o.pollingFrequency,
  669. "FORCE_REFRESH_INTERVAL": o.forceRefreshInterval,
  670. "POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
  671. "POLLING_SCHEDULER": o.pollingScheduler,
  672. "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT": o.mediaProxyHTTPClientTimeout,
  673. "MEDIA_PROXY_RESOURCE_TYPES": o.mediaProxyResourceTypes,
  674. "MEDIA_PROXY_MODE": o.mediaProxyMode,
  675. "MEDIA_PROXY_PRIVATE_KEY": mediaProxyPrivateKeyValue,
  676. "MEDIA_PROXY_CUSTOM_URL": o.mediaProxyCustomURL,
  677. "ROOT_URL": o.rootURL,
  678. "RUN_MIGRATIONS": o.runMigrations,
  679. "SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL": o.schedulerEntryFrequencyMaxInterval,
  680. "SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL": o.schedulerEntryFrequencyMinInterval,
  681. "SCHEDULER_ENTRY_FREQUENCY_FACTOR": o.schedulerEntryFrequencyFactor,
  682. "SCHEDULER_ROUND_ROBIN_MIN_INTERVAL": o.schedulerRoundRobinMinInterval,
  683. "SCHEDULER_ROUND_ROBIN_MAX_INTERVAL": o.schedulerRoundRobinMaxInterval,
  684. "SCHEDULER_SERVICE": o.schedulerService,
  685. "WATCHDOG": o.watchdog,
  686. "WORKER_POOL_SIZE": o.workerPoolSize,
  687. "YOUTUBE_API_KEY": redactSecretValue(o.youTubeApiKey, redactSecret),
  688. "YOUTUBE_EMBED_URL_OVERRIDE": o.youTubeEmbedUrlOverride,
  689. "WEBAUTHN": o.webAuthn,
  690. }
  691. keys := make([]string, 0, len(keyValues))
  692. for key := range keyValues {
  693. keys = append(keys, key)
  694. }
  695. sort.Strings(keys)
  696. var sortedOptions []*Option
  697. for _, key := range keys {
  698. sortedOptions = append(sortedOptions, &Option{Key: key, Value: keyValues[key]})
  699. }
  700. return sortedOptions
  701. }
  702. func (o *Options) String() string {
  703. var builder strings.Builder
  704. for _, option := range o.SortedOptions(false) {
  705. fmt.Fprintf(&builder, "%s=%v\n", option.Key, option.Value)
  706. }
  707. return builder.String()
  708. }
  709. func redactSecretValue(value string, redactSecret bool) string {
  710. if redactSecret && value != "" {
  711. return "<secret>"
  712. }
  713. return value
  714. }