options.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  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. 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. defaultPocketConsumerKey = ""
  73. defaultHTTPClientTimeout = 20
  74. defaultHTTPClientMaxBodySize = 15
  75. defaultHTTPClientProxy = ""
  76. defaultHTTPServerTimeout = 300
  77. defaultAuthProxyHeader = ""
  78. defaultAuthProxyUserCreation = false
  79. defaultMaintenanceMode = false
  80. defaultMaintenanceMessage = "Miniflux is currently under maintenance"
  81. defaultMetricsCollector = false
  82. defaultMetricsRefreshInterval = 60
  83. defaultMetricsAllowedNetworks = "127.0.0.1/8"
  84. defaultMetricsUsername = ""
  85. defaultMetricsPassword = ""
  86. defaultWatchdog = true
  87. defaultInvidiousInstance = "yewtu.be"
  88. defaultWebAuthn = false
  89. )
  90. var defaultHTTPClientUserAgent = "Mozilla/5.0 (compatible; Miniflux/" + version.Version + "; +https://miniflux.app)"
  91. // Option contains a key to value map of a single option. It may be used to output debug strings.
  92. type Option struct {
  93. Key string
  94. Value interface{}
  95. }
  96. // Options contains configuration options.
  97. type Options struct {
  98. HTTPS bool
  99. logFile string
  100. logDateTime bool
  101. logFormat string
  102. logLevel string
  103. hsts bool
  104. httpService bool
  105. schedulerService bool
  106. serverTimingHeader bool
  107. baseURL string
  108. rootURL string
  109. basePath string
  110. databaseURL string
  111. databaseMaxConns int
  112. databaseMinConns int
  113. databaseConnectionLifetime int
  114. runMigrations bool
  115. listenAddr string
  116. certFile string
  117. certDomain string
  118. certKeyFile string
  119. cleanupFrequencyHours int
  120. cleanupArchiveReadDays int
  121. cleanupArchiveUnreadDays int
  122. cleanupArchiveBatchSize int
  123. cleanupRemoveSessionsDays int
  124. pollingFrequency int
  125. forceRefreshInterval int
  126. batchSize int
  127. pollingScheduler string
  128. schedulerEntryFrequencyMinInterval int
  129. schedulerEntryFrequencyMaxInterval int
  130. schedulerEntryFrequencyFactor int
  131. schedulerRoundRobinMinInterval int
  132. pollingParsingErrorLimit int
  133. workerPoolSize int
  134. createAdmin bool
  135. adminUsername string
  136. adminPassword string
  137. mediaProxyHTTPClientTimeout int
  138. mediaProxyMode string
  139. mediaProxyResourceTypes []string
  140. mediaProxyCustomURL string
  141. fetchBilibiliWatchTime bool
  142. fetchNebulaWatchTime bool
  143. fetchOdyseeWatchTime bool
  144. fetchYouTubeWatchTime bool
  145. filterEntryMaxAgeDays int
  146. youTubeApiKey string
  147. youTubeEmbedUrlOverride 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. pocketConsumerKey string
  157. httpClientTimeout int
  158. httpClientMaxBodySize int64
  159. httpClientProxy 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. serverTimingHeader: defaultTiming,
  188. baseURL: defaultBaseURL,
  189. rootURL: defaultRootURL,
  190. basePath: defaultBasePath,
  191. databaseURL: defaultDatabaseURL,
  192. databaseMaxConns: defaultDatabaseMaxConns,
  193. databaseMinConns: defaultDatabaseMinConns,
  194. databaseConnectionLifetime: defaultDatabaseConnectionLifetime,
  195. runMigrations: defaultRunMigrations,
  196. listenAddr: defaultListenAddr,
  197. certFile: defaultCertFile,
  198. certDomain: defaultCertDomain,
  199. certKeyFile: defaultKeyFile,
  200. cleanupFrequencyHours: defaultCleanupFrequencyHours,
  201. cleanupArchiveReadDays: defaultCleanupArchiveReadDays,
  202. cleanupArchiveUnreadDays: defaultCleanupArchiveUnreadDays,
  203. cleanupArchiveBatchSize: defaultCleanupArchiveBatchSize,
  204. cleanupRemoveSessionsDays: defaultCleanupRemoveSessionsDays,
  205. pollingFrequency: defaultPollingFrequency,
  206. forceRefreshInterval: defaultForceRefreshInterval,
  207. batchSize: defaultBatchSize,
  208. pollingScheduler: defaultPollingScheduler,
  209. schedulerEntryFrequencyMinInterval: defaultSchedulerEntryFrequencyMinInterval,
  210. schedulerEntryFrequencyMaxInterval: defaultSchedulerEntryFrequencyMaxInterval,
  211. schedulerEntryFrequencyFactor: defaultSchedulerEntryFrequencyFactor,
  212. schedulerRoundRobinMinInterval: defaultSchedulerRoundRobinMinInterval,
  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. pocketConsumerKey: defaultPocketConsumerKey,
  236. httpClientTimeout: defaultHTTPClientTimeout,
  237. httpClientMaxBodySize: defaultHTTPClientMaxBodySize * 1024 * 1024,
  238. httpClientProxy: defaultHTTPClientProxy,
  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. // HasServerTimingHeader returns true if server-timing headers enabled.
  284. func (o *Options) HasServerTimingHeader() bool {
  285. return o.serverTimingHeader
  286. }
  287. // BaseURL returns the application base URL with path.
  288. func (o *Options) BaseURL() string {
  289. return o.baseURL
  290. }
  291. // RootURL returns the base URL without path.
  292. func (o *Options) RootURL() string {
  293. return o.rootURL
  294. }
  295. // BasePath returns the application base path according to the base URL.
  296. func (o *Options) BasePath() string {
  297. return o.basePath
  298. }
  299. // IsDefaultDatabaseURL returns true if the default database URL is used.
  300. func (o *Options) IsDefaultDatabaseURL() bool {
  301. return o.databaseURL == defaultDatabaseURL
  302. }
  303. // DatabaseURL returns the database URL.
  304. func (o *Options) DatabaseURL() string {
  305. return o.databaseURL
  306. }
  307. // DatabaseMaxConns returns the maximum number of database connections.
  308. func (o *Options) DatabaseMaxConns() int {
  309. return o.databaseMaxConns
  310. }
  311. // DatabaseMinConns returns the minimum number of database connections.
  312. func (o *Options) DatabaseMinConns() int {
  313. return o.databaseMinConns
  314. }
  315. // DatabaseConnectionLifetime returns the maximum amount of time a connection may be reused.
  316. func (o *Options) DatabaseConnectionLifetime() time.Duration {
  317. return time.Duration(o.databaseConnectionLifetime) * time.Minute
  318. }
  319. // ListenAddr returns the listen address for the HTTP server.
  320. func (o *Options) ListenAddr() string {
  321. return o.listenAddr
  322. }
  323. // CertFile returns the SSL certificate filename if any.
  324. func (o *Options) CertFile() string {
  325. return o.certFile
  326. }
  327. // CertKeyFile returns the private key filename for custom SSL certificate.
  328. func (o *Options) CertKeyFile() string {
  329. return o.certKeyFile
  330. }
  331. // CertDomain returns the domain to use for Let's Encrypt certificate.
  332. func (o *Options) CertDomain() string {
  333. return o.certDomain
  334. }
  335. // CleanupFrequencyHours returns the interval in hours for cleanup jobs.
  336. func (o *Options) CleanupFrequencyHours() int {
  337. return o.cleanupFrequencyHours
  338. }
  339. // CleanupArchiveReadDays returns the number of days after which marking read items as removed.
  340. func (o *Options) CleanupArchiveReadDays() int {
  341. return o.cleanupArchiveReadDays
  342. }
  343. // CleanupArchiveUnreadDays returns the number of days after which marking unread items as removed.
  344. func (o *Options) CleanupArchiveUnreadDays() int {
  345. return o.cleanupArchiveUnreadDays
  346. }
  347. // CleanupArchiveBatchSize returns the number of entries to archive for each interval.
  348. func (o *Options) CleanupArchiveBatchSize() int {
  349. return o.cleanupArchiveBatchSize
  350. }
  351. // CleanupRemoveSessionsDays returns the number of days after which to remove sessions.
  352. func (o *Options) CleanupRemoveSessionsDays() int {
  353. return o.cleanupRemoveSessionsDays
  354. }
  355. // WorkerPoolSize returns the number of background worker.
  356. func (o *Options) WorkerPoolSize() int {
  357. return o.workerPoolSize
  358. }
  359. // PollingFrequency returns the interval to refresh feeds in the background.
  360. func (o *Options) PollingFrequency() int {
  361. return o.pollingFrequency
  362. }
  363. // ForceRefreshInterval returns the force refresh interval
  364. func (o *Options) ForceRefreshInterval() int {
  365. return o.forceRefreshInterval
  366. }
  367. // BatchSize returns the number of feeds to send for background processing.
  368. func (o *Options) BatchSize() int {
  369. return o.batchSize
  370. }
  371. // PollingScheduler returns the scheduler used for polling feeds.
  372. func (o *Options) PollingScheduler() string {
  373. return o.pollingScheduler
  374. }
  375. // SchedulerEntryFrequencyMaxInterval returns the maximum interval in minutes for the entry frequency scheduler.
  376. func (o *Options) SchedulerEntryFrequencyMaxInterval() int {
  377. return o.schedulerEntryFrequencyMaxInterval
  378. }
  379. // SchedulerEntryFrequencyMinInterval returns the minimum interval in minutes for the entry frequency scheduler.
  380. func (o *Options) SchedulerEntryFrequencyMinInterval() int {
  381. return o.schedulerEntryFrequencyMinInterval
  382. }
  383. // SchedulerEntryFrequencyFactor returns the factor for the entry frequency scheduler.
  384. func (o *Options) SchedulerEntryFrequencyFactor() int {
  385. return o.schedulerEntryFrequencyFactor
  386. }
  387. func (o *Options) SchedulerRoundRobinMinInterval() int {
  388. return o.schedulerRoundRobinMinInterval
  389. }
  390. // PollingParsingErrorLimit returns the limit of errors when to stop polling.
  391. func (o *Options) PollingParsingErrorLimit() int {
  392. return o.pollingParsingErrorLimit
  393. }
  394. // IsOAuth2UserCreationAllowed returns true if user creation is allowed for OAuth2 users.
  395. func (o *Options) IsOAuth2UserCreationAllowed() bool {
  396. return o.oauth2UserCreationAllowed
  397. }
  398. // OAuth2ClientID returns the OAuth2 Client ID.
  399. func (o *Options) OAuth2ClientID() string {
  400. return o.oauth2ClientID
  401. }
  402. // OAuth2ClientSecret returns the OAuth2 client secret.
  403. func (o *Options) OAuth2ClientSecret() string {
  404. return o.oauth2ClientSecret
  405. }
  406. // OAuth2RedirectURL returns the OAuth2 redirect URL.
  407. func (o *Options) OAuth2RedirectURL() string {
  408. return o.oauth2RedirectURL
  409. }
  410. // OIDCDiscoveryEndpoint returns the OAuth2 OIDC discovery endpoint.
  411. func (o *Options) OIDCDiscoveryEndpoint() string {
  412. return o.oidcDiscoveryEndpoint
  413. }
  414. // OIDCProviderName returns the OAuth2 OIDC provider's display name
  415. func (o *Options) OIDCProviderName() string {
  416. return o.oidcProviderName
  417. }
  418. // OAuth2Provider returns the name of the OAuth2 provider configured.
  419. func (o *Options) OAuth2Provider() string {
  420. return o.oauth2Provider
  421. }
  422. // DisableLocalAUth returns true if the local user database should not be used to authenticate users
  423. func (o *Options) DisableLocalAuth() bool {
  424. return o.disableLocalAuth
  425. }
  426. // HasHSTS returns true if HTTP Strict Transport Security is enabled.
  427. func (o *Options) HasHSTS() bool {
  428. return o.hsts
  429. }
  430. // RunMigrations returns true if the environment variable RUN_MIGRATIONS is not empty.
  431. func (o *Options) RunMigrations() bool {
  432. return o.runMigrations
  433. }
  434. // CreateAdmin returns true if the environment variable CREATE_ADMIN is not empty.
  435. func (o *Options) CreateAdmin() bool {
  436. return o.createAdmin
  437. }
  438. // AdminUsername returns the admin username if defined.
  439. func (o *Options) AdminUsername() string {
  440. return o.adminUsername
  441. }
  442. // AdminPassword returns the admin password if defined.
  443. func (o *Options) AdminPassword() string {
  444. return o.adminPassword
  445. }
  446. // FetchYouTubeWatchTime returns true if the YouTube video duration
  447. // should be fetched and used as a reading time.
  448. func (o *Options) FetchYouTubeWatchTime() bool {
  449. return o.fetchYouTubeWatchTime
  450. }
  451. // YouTubeApiKey returns the YouTube API key if defined.
  452. func (o *Options) YouTubeApiKey() string {
  453. return o.youTubeApiKey
  454. }
  455. // YouTubeEmbedUrlOverride returns YouTube URL which will be used for embeds
  456. func (o *Options) YouTubeEmbedUrlOverride() string {
  457. return o.youTubeEmbedUrlOverride
  458. }
  459. // FetchNebulaWatchTime returns true if the Nebula video duration
  460. // should be fetched and used as a reading time.
  461. func (o *Options) FetchNebulaWatchTime() bool {
  462. return o.fetchNebulaWatchTime
  463. }
  464. // FetchOdyseeWatchTime returns true if the Odysee video duration
  465. // should be fetched and used as a reading time.
  466. func (o *Options) FetchOdyseeWatchTime() bool {
  467. return o.fetchOdyseeWatchTime
  468. }
  469. // FetchBilibiliWatchTime returns true if the Bilibili video duration
  470. // should be fetched and used as a reading time.
  471. func (o *Options) FetchBilibiliWatchTime() bool {
  472. return o.fetchBilibiliWatchTime
  473. }
  474. // MediaProxyMode returns "none" to never proxy, "http-only" to proxy non-HTTPS, "all" to always proxy.
  475. func (o *Options) MediaProxyMode() string {
  476. return o.mediaProxyMode
  477. }
  478. // MediaProxyResourceTypes returns a slice of resource types to proxy.
  479. func (o *Options) MediaProxyResourceTypes() []string {
  480. return o.mediaProxyResourceTypes
  481. }
  482. // MediaCustomProxyURL returns the custom proxy URL for medias.
  483. func (o *Options) MediaCustomProxyURL() string {
  484. return o.mediaProxyCustomURL
  485. }
  486. // MediaProxyHTTPClientTimeout returns the time limit in seconds before the proxy HTTP client cancel the request.
  487. func (o *Options) MediaProxyHTTPClientTimeout() int {
  488. return o.mediaProxyHTTPClientTimeout
  489. }
  490. // MediaProxyPrivateKey returns the private key used by the media proxy.
  491. func (o *Options) MediaProxyPrivateKey() []byte {
  492. return o.mediaProxyPrivateKey
  493. }
  494. // HasHTTPService returns true if the HTTP service is enabled.
  495. func (o *Options) HasHTTPService() bool {
  496. return o.httpService
  497. }
  498. // HasSchedulerService returns true if the scheduler service is enabled.
  499. func (o *Options) HasSchedulerService() bool {
  500. return o.schedulerService
  501. }
  502. // PocketConsumerKey returns the Pocket Consumer Key if configured.
  503. func (o *Options) PocketConsumerKey(defaultValue string) string {
  504. if o.pocketConsumerKey != "" {
  505. return o.pocketConsumerKey
  506. }
  507. return defaultValue
  508. }
  509. // HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request.
  510. func (o *Options) HTTPClientTimeout() int {
  511. return o.httpClientTimeout
  512. }
  513. // HTTPClientMaxBodySize returns the number of bytes allowed for the HTTP client to transfer.
  514. func (o *Options) HTTPClientMaxBodySize() int64 {
  515. return o.httpClientMaxBodySize
  516. }
  517. // HTTPClientProxy returns the proxy URL for HTTP client.
  518. func (o *Options) HTTPClientProxy() string {
  519. return o.httpClientProxy
  520. }
  521. // HTTPServerTimeout returns the time limit in seconds before the HTTP server cancel the request.
  522. func (o *Options) HTTPServerTimeout() int {
  523. return o.httpServerTimeout
  524. }
  525. // HasHTTPClientProxyConfigured returns true if the HTTP proxy is configured.
  526. func (o *Options) HasHTTPClientProxyConfigured() bool {
  527. return o.httpClientProxy != ""
  528. }
  529. // AuthProxyHeader returns an HTTP header name that contains username for
  530. // authentication using auth proxy.
  531. func (o *Options) AuthProxyHeader() string {
  532. return o.authProxyHeader
  533. }
  534. // IsAuthProxyUserCreationAllowed returns true if user creation is allowed for
  535. // users authenticated using auth proxy.
  536. func (o *Options) IsAuthProxyUserCreationAllowed() bool {
  537. return o.authProxyUserCreation
  538. }
  539. // HasMetricsCollector returns true if metrics collection is enabled.
  540. func (o *Options) HasMetricsCollector() bool {
  541. return o.metricsCollector
  542. }
  543. // MetricsRefreshInterval returns the refresh interval in seconds.
  544. func (o *Options) MetricsRefreshInterval() int {
  545. return o.metricsRefreshInterval
  546. }
  547. // MetricsAllowedNetworks returns the list of networks allowed to connect to the metrics endpoint.
  548. func (o *Options) MetricsAllowedNetworks() []string {
  549. return o.metricsAllowedNetworks
  550. }
  551. func (o *Options) MetricsUsername() string {
  552. return o.metricsUsername
  553. }
  554. func (o *Options) MetricsPassword() string {
  555. return o.metricsPassword
  556. }
  557. // HTTPClientUserAgent returns the global User-Agent header for miniflux.
  558. func (o *Options) HTTPClientUserAgent() string {
  559. return o.httpClientUserAgent
  560. }
  561. // HasWatchdog returns true if the systemd watchdog is enabled.
  562. func (o *Options) HasWatchdog() bool {
  563. return o.watchdog
  564. }
  565. // InvidiousInstance returns the invidious instance used by miniflux
  566. func (o *Options) InvidiousInstance() string {
  567. return o.invidiousInstance
  568. }
  569. // WebAuthn returns true if WebAuthn logins are supported
  570. func (o *Options) WebAuthn() bool {
  571. return o.webAuthn
  572. }
  573. // FilterEntryMaxAgeDays returns the number of days after which entries should be retained.
  574. func (o *Options) FilterEntryMaxAgeDays() int {
  575. return o.filterEntryMaxAgeDays
  576. }
  577. // SortedOptions returns options as a list of key value pairs, sorted by keys.
  578. func (o *Options) SortedOptions(redactSecret bool) []*Option {
  579. var keyValues = map[string]interface{}{
  580. "ADMIN_PASSWORD": redactSecretValue(o.adminPassword, redactSecret),
  581. "ADMIN_USERNAME": o.adminUsername,
  582. "AUTH_PROXY_HEADER": o.authProxyHeader,
  583. "AUTH_PROXY_USER_CREATION": o.authProxyUserCreation,
  584. "BASE_PATH": o.basePath,
  585. "BASE_URL": o.baseURL,
  586. "BATCH_SIZE": o.batchSize,
  587. "CERT_DOMAIN": o.certDomain,
  588. "CERT_FILE": o.certFile,
  589. "CLEANUP_ARCHIVE_BATCH_SIZE": o.cleanupArchiveBatchSize,
  590. "CLEANUP_ARCHIVE_READ_DAYS": o.cleanupArchiveReadDays,
  591. "CLEANUP_ARCHIVE_UNREAD_DAYS": o.cleanupArchiveUnreadDays,
  592. "CLEANUP_FREQUENCY_HOURS": o.cleanupFrequencyHours,
  593. "CLEANUP_REMOVE_SESSIONS_DAYS": o.cleanupRemoveSessionsDays,
  594. "CREATE_ADMIN": o.createAdmin,
  595. "DATABASE_CONNECTION_LIFETIME": o.databaseConnectionLifetime,
  596. "DATABASE_MAX_CONNS": o.databaseMaxConns,
  597. "DATABASE_MIN_CONNS": o.databaseMinConns,
  598. "DATABASE_URL": redactSecretValue(o.databaseURL, redactSecret),
  599. "DISABLE_HSTS": !o.hsts,
  600. "DISABLE_HTTP_SERVICE": !o.httpService,
  601. "DISABLE_SCHEDULER_SERVICE": !o.schedulerService,
  602. "FILTER_ENTRY_MAX_AGE_DAYS": o.filterEntryMaxAgeDays,
  603. "FETCH_YOUTUBE_WATCH_TIME": o.fetchYouTubeWatchTime,
  604. "FETCH_NEBULA_WATCH_TIME": o.fetchNebulaWatchTime,
  605. "FETCH_ODYSEE_WATCH_TIME": o.fetchOdyseeWatchTime,
  606. "FETCH_BILIBILI_WATCH_TIME": o.fetchBilibiliWatchTime,
  607. "HTTPS": o.HTTPS,
  608. "HTTP_CLIENT_MAX_BODY_SIZE": o.httpClientMaxBodySize,
  609. "HTTP_CLIENT_PROXY": o.httpClientProxy,
  610. "HTTP_CLIENT_TIMEOUT": o.httpClientTimeout,
  611. "HTTP_CLIENT_USER_AGENT": o.httpClientUserAgent,
  612. "HTTP_SERVER_TIMEOUT": o.httpServerTimeout,
  613. "HTTP_SERVICE": o.httpService,
  614. "INVIDIOUS_INSTANCE": o.invidiousInstance,
  615. "KEY_FILE": o.certKeyFile,
  616. "LISTEN_ADDR": o.listenAddr,
  617. "LOG_FILE": o.logFile,
  618. "LOG_DATE_TIME": o.logDateTime,
  619. "LOG_FORMAT": o.logFormat,
  620. "LOG_LEVEL": o.logLevel,
  621. "MAINTENANCE_MESSAGE": o.maintenanceMessage,
  622. "MAINTENANCE_MODE": o.maintenanceMode,
  623. "METRICS_ALLOWED_NETWORKS": strings.Join(o.metricsAllowedNetworks, ","),
  624. "METRICS_COLLECTOR": o.metricsCollector,
  625. "METRICS_PASSWORD": redactSecretValue(o.metricsPassword, redactSecret),
  626. "METRICS_REFRESH_INTERVAL": o.metricsRefreshInterval,
  627. "METRICS_USERNAME": o.metricsUsername,
  628. "OAUTH2_CLIENT_ID": o.oauth2ClientID,
  629. "OAUTH2_CLIENT_SECRET": redactSecretValue(o.oauth2ClientSecret, redactSecret),
  630. "OAUTH2_OIDC_DISCOVERY_ENDPOINT": o.oidcDiscoveryEndpoint,
  631. "OAUTH2_OIDC_PROVIDER_NAME": o.oidcProviderName,
  632. "OAUTH2_PROVIDER": o.oauth2Provider,
  633. "OAUTH2_REDIRECT_URL": o.oauth2RedirectURL,
  634. "OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
  635. "DISABLE_LOCAL_AUTH": o.disableLocalAuth,
  636. "POCKET_CONSUMER_KEY": redactSecretValue(o.pocketConsumerKey, redactSecret),
  637. "POLLING_FREQUENCY": o.pollingFrequency,
  638. "FORCE_REFRESH_INTERVAL": o.forceRefreshInterval,
  639. "POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
  640. "POLLING_SCHEDULER": o.pollingScheduler,
  641. "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT": o.mediaProxyHTTPClientTimeout,
  642. "MEDIA_PROXY_RESOURCE_TYPES": o.mediaProxyResourceTypes,
  643. "MEDIA_PROXY_MODE": o.mediaProxyMode,
  644. "MEDIA_PROXY_PRIVATE_KEY": redactSecretValue(string(o.mediaProxyPrivateKey), redactSecret),
  645. "MEDIA_PROXY_CUSTOM_URL": o.mediaProxyCustomURL,
  646. "ROOT_URL": o.rootURL,
  647. "RUN_MIGRATIONS": o.runMigrations,
  648. "SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL": o.schedulerEntryFrequencyMaxInterval,
  649. "SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL": o.schedulerEntryFrequencyMinInterval,
  650. "SCHEDULER_ENTRY_FREQUENCY_FACTOR": o.schedulerEntryFrequencyFactor,
  651. "SCHEDULER_ROUND_ROBIN_MIN_INTERVAL": o.schedulerRoundRobinMinInterval,
  652. "SCHEDULER_SERVICE": o.schedulerService,
  653. "SERVER_TIMING_HEADER": o.serverTimingHeader,
  654. "WATCHDOG": o.watchdog,
  655. "WORKER_POOL_SIZE": o.workerPoolSize,
  656. "YOUTUBE_API_KEY": redactSecretValue(o.youTubeApiKey, redactSecret),
  657. "YOUTUBE_EMBED_URL_OVERRIDE": o.youTubeEmbedUrlOverride,
  658. "WEBAUTHN": o.webAuthn,
  659. }
  660. keys := make([]string, 0, len(keyValues))
  661. for key := range keyValues {
  662. keys = append(keys, key)
  663. }
  664. sort.Strings(keys)
  665. var sortedOptions []*Option
  666. for _, key := range keys {
  667. sortedOptions = append(sortedOptions, &Option{Key: key, Value: keyValues[key]})
  668. }
  669. return sortedOptions
  670. }
  671. func (o *Options) String() string {
  672. var builder strings.Builder
  673. for _, option := range o.SortedOptions(false) {
  674. fmt.Fprintf(&builder, "%s=%v\n", option.Key, option.Value)
  675. }
  676. return builder.String()
  677. }
  678. func redactSecretValue(value string, redactSecret bool) string {
  679. if redactSecret && value != "" {
  680. return "<secret>"
  681. }
  682. return value
  683. }