options.go 31 KB

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