options.go 30 KB

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