diff options
| -rw-r--r-- | locales/el.json | 8 | ||||
| -rw-r--r-- | locales/fi.json | 456 | ||||
| -rw-r--r-- | locales/hu-HU.json | 6 | ||||
| -rw-r--r-- | locales/id.json | 2 | ||||
| -rw-r--r-- | src/invidious.cr | 45 | ||||
| -rw-r--r-- | src/invidious/helpers/errors.cr | 32 | ||||
| -rw-r--r-- | src/invidious/helpers/helpers.cr | 57 | ||||
| -rw-r--r-- | src/invidious/helpers/logger.cr | 2 | ||||
| -rw-r--r-- | src/invidious/helpers/utils.cr | 12 | ||||
| -rw-r--r-- | src/invidious/jobs/bypass_captcha_job.cr | 29 | ||||
| -rw-r--r-- | src/invidious/jobs/refresh_channels_job.cr | 7 | ||||
| -rw-r--r-- | src/invidious/jobs/refresh_feeds_job.cr | 5 | ||||
| -rw-r--r-- | src/invidious/jobs/statistics_refresh_job.cr | 5 | ||||
| -rw-r--r-- | src/invidious/jobs/subscribe_to_feeds_job.cr | 9 | ||||
| -rw-r--r-- | src/invidious/routes/base_route.cr | 4 | ||||
| -rw-r--r-- | src/invidious/routes/login.cr | 24 | ||||
| -rw-r--r-- | src/invidious/routes/user_preferences.cr | 31 | ||||
| -rw-r--r-- | src/invidious/routing.cr | 4 | ||||
| -rw-r--r-- | src/invidious/views/preferences.ecr | 14 | ||||
| -rw-r--r-- | src/invidious/views/template.ecr | 2 |
20 files changed, 398 insertions, 356 deletions
diff --git a/locales/el.json b/locales/el.json index 23b3cdf9..f74f2421 100644 --- a/locales/el.json +++ b/locales/el.json @@ -1,11 +1,11 @@ { - "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομητής", + "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομητές.([^.,0-9]|^)1([^.,0-9]|$)", "`x` subscribers.": "`x` συνδρομητές.", - "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` βίντεο", + "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` βίντεο.([^.,0-9]|^)1([^.,0-9]|$)", "`x` videos.": "`x` βίντεο.", - "`x` playlists": "`x` κατάλογοι αναπαραγωγής", + "`x` playlists": "`x` λίστες αναπαραγωγής", "LIVE": "ΖΩΝΤΑΝΑ", - "Shared `x` ago": "Μοιράστηκε πριν `x`", + "Shared `x` ago": "Μοιράστηκε πριν από `x`", "Unsubscribe": "Απεγγραφή", "Subscribe": "Εγγραφή", "View channel on YouTube": "Προβολή καναλιού στο YouTube", diff --git a/locales/fi.json b/locales/fi.json index 7de46bf4..0b2db9a1 100644 --- a/locales/fi.json +++ b/locales/fi.json @@ -118,236 +118,236 @@ "Token": "Tunnus", "`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tilausta.([^.,0-9]|^)1([^.,0-9]|$)", "`x` subscriptions.": "`x` tilausta.", - "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` tokens.": "", + "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tunnistetta.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` tokens.": "`x` tunnistetta.", "Import/export": "Tuo/vie", "unsubscribe": "peru tilaus", "revoke": "kumoa", "Subscriptions": "Tilaukset", - "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` unseen notifications.": "", - "search": "", - "Log out": "", - "Released under the AGPLv3 by Omar Roth.": "", - "Source available here.": "", - "View JavaScript license information.": "", - "View privacy policy.": "", - "Trending": "", - "Public": "", - "Unlisted": "", - "Private": "", - "View all playlists": "", - "Updated `x` ago": "", - "Delete playlist `x`?": "", - "Delete playlist": "", - "Create playlist": "", - "Title": "", - "Playlist privacy": "", - "Editing playlist `x`": "", - "Watch on YouTube": "", - "Hide annotations": "", - "Show annotations": "", - "Genre: ": "", - "License: ": "", - "Family friendly? ": "", - "Wilson score: ": "", - "Engagement: ": "", - "Whitelisted regions: ": "", - "Blacklisted regions: ": "", - "Shared `x`": "", - "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` views.": "", - "Premieres in `x`": "", - "Premieres `x`": "", - "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", - "View YouTube comments": "", - "View more comments on Reddit": "", - "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "", - "View `x` comments.": "", - "View Reddit comments": "", - "Hide replies": "", - "Show replies": "", - "Incorrect password": "", - "Quota exceeded, try again in a few hours": "", - "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", - "Invalid TFA code": "", - "Login failed. This may be because two-factor authentication is not turned on for your account.": "", - "Wrong answer": "", - "Erroneous CAPTCHA": "", - "CAPTCHA is a required field": "", - "User ID is a required field": "", - "Password is a required field": "", - "Wrong username or password": "", - "Please sign in using 'Log in with Google'": "", - "Password cannot be empty": "", - "Password cannot be longer than 55 characters": "", - "Please log in": "", - "Invidious Private Feed for `x`": "", - "channel:`x`": "", - "Deleted or invalid channel": "", - "This channel does not exist.": "", - "Could not get channel info.": "", - "Could not fetch comments": "", - "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "", - "View `x` replies.": "", - "`x` ago": "", - "Load more": "", - "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` points.": "", - "Could not create mix.": "", - "Empty playlist": "", - "Not a playlist.": "", - "Playlist does not exist.": "", - "Could not pull trending pages.": "", - "Hidden field \"challenge\" is a required field": "", - "Hidden field \"token\" is a required field": "", - "Erroneous challenge": "", - "Erroneous token": "", - "No such user": "", - "Token is expired, please try again": "", - "English": "", - "English (auto-generated)": "", - "Afrikaans": "", - "Albanian": "", - "Amharic": "", - "Arabic": "", - "Armenian": "", - "Azerbaijani": "", - "Bangla": "", - "Basque": "", - "Belarusian": "", - "Bosnian": "", - "Bulgarian": "", - "Burmese": "", - "Catalan": "", - "Cebuano": "", - "Chinese (Simplified)": "", - "Chinese (Traditional)": "", - "Corsican": "", - "Croatian": "", - "Czech": "", - "Danish": "", - "Dutch": "", - "Esperanto": "", - "Estonian": "", - "Filipino": "", - "Finnish": "", - "French": "", - "Galician": "", - "Georgian": "", - "German": "", - "Greek": "", - "Gujarati": "", - "Haitian Creole": "", - "Hausa": "", - "Hawaiian": "", - "Hebrew": "", - "Hindi": "", - "Hmong": "", - "Hungarian": "", - "Icelandic": "", - "Igbo": "", - "Indonesian": "", - "Irish": "", - "Italian": "", - "Japanese": "", - "Javanese": "", - "Kannada": "", - "Kazakh": "", - "Khmer": "", - "Korean": "", - "Kurdish": "", - "Kyrgyz": "", - "Lao": "", - "Latin": "", - "Latvian": "", - "Lithuanian": "", - "Luxembourgish": "", - "Macedonian": "", - "Malagasy": "", - "Malay": "", - "Malayalam": "", - "Maltese": "", - "Maori": "", - "Marathi": "", - "Mongolian": "", - "Nepali": "", - "Norwegian Bokmål": "", - "Nyanja": "", - "Pashto": "", - "Persian": "", - "Polish": "", - "Portuguese": "", - "Punjabi": "", - "Romanian": "", - "Russian": "", - "Samoan": "", - "Scottish Gaelic": "", - "Serbian": "", - "Shona": "", - "Sindhi": "", - "Sinhala": "", - "Slovak": "", - "Slovenian": "", - "Somali": "", - "Southern Sotho": "", - "Spanish": "", - "Spanish (Latin America)": "", - "Sundanese": "", - "Swahili": "", - "Swedish": "", - "Tajik": "", - "Tamil": "", - "Telugu": "", - "Thai": "", - "Turkish": "", - "Ukrainian": "", - "Urdu": "", - "Uzbek": "", - "Vietnamese": "", - "Welsh": "", - "Western Frisian": "", - "Xhosa": "", - "Yiddish": "", - "Yoruba": "", - "Zulu": "", - "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` years.": "", - "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` months.": "", - "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` weeks.": "", - "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` days.": "", - "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` hours.": "", - "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` minutes.": "", - "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "", - "`x` seconds.": "", - "Fallback comments: ": "", - "Popular": "", - "Top": "", - "About": "", - "Rating: ": "", - "Language: ": "", - "View as playlist": "", - "Default": "", - "Music": "", - "Gaming": "", - "News": "", - "Movies": "", - "Download": "", - "Download as: ": "", - "%A %B %-d, %Y": "", - "(edited)": "", - "YouTube comment permalink": "", - "permalink": "", - "`x` marked it with a ❤": "", - "Audio mode": "", - "Video mode": "", - "Videos": "", - "Playlists": "", - "Community": "", - "Current version: ": "" + "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "`x` näkemätöntä ilmoitusta.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` unseen notifications.": "`x` näkemätöntä ilmoitusta.", + "search": "haku", + "Log out": "Kirjaudu ulos", + "Released under the AGPLv3 by Omar Roth.": "Julkaissut AGPLv3-lisenssillä: Omar Roth.", + "Source available here.": "Lähdekoodi on saatavilla täällä.", + "View JavaScript license information.": "JavaScript-koodin lisenssit.", + "View privacy policy.": "Katso tietosuojaseloste.", + "Trending": "Nousussa", + "Public": "Julkinen", + "Unlisted": "Listaamaton", + "Private": "Yksityinen", + "View all playlists": "Kaikki soittolistat", + "Updated `x` ago": "Päivitetty `x` sitten", + "Delete playlist `x`?": "Poistetaanko soittolista `x`?", + "Delete playlist": "Poista soittolista", + "Create playlist": "Luo soittolista", + "Title": "Nimi", + "Playlist privacy": "Soittolistan yksityisyys", + "Editing playlist `x`": "Muokataan soittolistaa `x`", + "Watch on YouTube": "Katso YouTubessa", + "Hide annotations": "Piilota merkkaukset", + "Show annotations": "Näytä merkkaukset", + "Genre: ": "Genre: ", + "License: ": "Lisenssi: ", + "Family friendly? ": "Kaiken ikäisille sopiva? ", + "Wilson score: ": "Wilson-pistemäärä: ", + "Engagement: ": "Huomio: ", + "Whitelisted regions: ": "valkolistatut alueet: ", + "Blacklisted regions: ": "mustalla listalla olevat alueet: ", + "Shared `x`": "Jaettu `x`", + "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "`x` katselukertaa.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` views.": "`x` katselukertaa.", + "Premieres in `x`": "Ensiesitykseen aikaa `x`", + "Premieres `x`": "Ensiesitykseen `x`", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hei! Vaikuttaa siltä, että sinulla on JavaScript pois käytöstä. Klikkaa tästä nähdäksesi kommentit, huomioi että lataamisessa voi kestää melko kauan.", + "View YouTube comments": "Näytä YouTube-kommentit", + "View more comments on Reddit": "Katso lisää kommentteja Redditissä", + "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "Näytä `x` komenttia.([^.,0-9]|^)1([^.,0-9]|$)", + "View `x` comments.": "Näytä `x` kommenttia.", + "View Reddit comments": "Näytä Reddit-kommentit", + "Hide replies": "Piilota vastaukset", + "Show replies": "Näytä vastaukset", + "Incorrect password": "Väärä salasana", + "Quota exceeded, try again in a few hours": "Kiintiö ylitetty, yritä parin tunnin kuluttua uudestaan", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Sisäänkirjautuminen epäonnistui. Varmista, että kaksivaiheinen tunnistautuminen (Authenticator tai tekstiviesti) on käytössä.", + "Invalid TFA code": "Virheellinen turvakoodi", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "Sisäänkirjautuminen epäonnistui. Tämä voi johtua siitä, että kaksivaiheinen tunnistautuminen on pois käytöstä tunnuksellasi.", + "Wrong answer": "Väärä vastaus", + "Erroneous CAPTCHA": "Virheellinen CAPTCHA", + "CAPTCHA is a required field": "CAPTCHA-kenttä vaaditaan", + "User ID is a required field": "Käyttäjätunnus vaaditaan", + "Password is a required field": "Salasana vaaditaan", + "Wrong username or password": "Väärä käyttäjänimi tai salasana", + "Please sign in using 'Log in with Google'": "Ole hyvä ja kirjaudu sisään Google-tunnuksella", + "Password cannot be empty": "Salasana ei voi olla tyhjä", + "Password cannot be longer than 55 characters": "Salasana ei voi olla yli 55 merkkiä pitkä", + "Please log in": "Kirjaudu sisään, ole hyvä", + "Invidious Private Feed for `x`": "Invidousin yksityinen syöte `x`:lle", + "channel:`x`": "kanava:`x`", + "Deleted or invalid channel": "Poistettu tai virheellinen kanava", + "This channel does not exist.": "Tätä kanavaa ei ole olemassa.", + "Could not get channel info.": "Kanavatietoa ei saatu ladattua.", + "Could not fetch comments": "Kommenttien nouto epäonnistui", + "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "Näytä `x` vastausta.([^.,0-9]|^)1([^.,0-9]|$)", + "View `x` replies.": "Näytä `x` vastausta.", + "`x` ago": "`x` sitten", + "Load more": "Lataa lisää", + "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "`x` pistettä.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` points.": "`x` pistettä.", + "Could not create mix.": "Sekoituksen luominen epäonnistui.", + "Empty playlist": "Tyhjennä soittolista", + "Not a playlist.": "Ei ole soittolista.", + "Playlist does not exist.": "Soittolistaa ei ole olemassa.", + "Could not pull trending pages.": "Nousussa olevien sivujen lataus epäonnitui.", + "Hidden field \"challenge\" is a required field": "Piilotettu kenttä \"challenge\" on vaaditaan", + "Hidden field \"token\" is a required field": "Piilotettu kenttä \"tunniste\" vaaditaan", + "Erroneous challenge": "Virheellinen haaste", + "Erroneous token": "Virheellinen tunniste", + "No such user": "Käyttäjää ei ole olemassa", + "Token is expired, please try again": "Tunniste on vanhentunut, yritä uudestaan", + "English": "englanti", + "English (auto-generated)": "englanti (automaattisesti luotu)", + "Afrikaans": "afrikaans", + "Albanian": "albania", + "Amharic": "amhara", + "Arabic": "arabia", + "Armenian": "armenia", + "Azerbaijani": "azeri", + "Bangla": "bengali", + "Basque": "baski", + "Belarusian": "valkovenäjä", + "Bosnian": "bosnia", + "Bulgarian": "bulgaria", + "Burmese": "burma", + "Catalan": "katalaani", + "Cebuano": "cebuano", + "Chinese (Simplified)": "kiina (yksinkertaistettu)", + "Chinese (Traditional)": "kiina (perinteinen)", + "Corsican": "korsika", + "Croatian": "kroaatti", + "Czech": "tšekki", + "Danish": "tanska", + "Dutch": "hollanti", + "Esperanto": "esperanto", + "Estonian": "eesti", + "Filipino": "filipino", + "Finnish": "suomi", + "French": "ranska", + "Galician": "galego", + "Georgian": "georgia", + "German": "saksa", + "Greek": "kreikka", + "Gujarati": "gujarati", + "Haitian Creole": "haitinkreoli", + "Hausa": "hausa", + "Hawaiian": "havaiji", + "Hebrew": "heprea", + "Hindi": "hindi", + "Hmong": "hmong", + "Hungarian": "unkari", + "Icelandic": "islanti", + "Igbo": "igbo", + "Indonesian": "indonesia", + "Irish": "iiri", + "Italian": "italia", + "Japanese": "japani", + "Javanese": "jaava", + "Kannada": "kannada", + "Kazakh": "kazakki", + "Khmer": "khmer", + "Korean": "korea", + "Kurdish": "kurdi", + "Kyrgyz": "kirgiisi", + "Lao": "lao", + "Latin": "latina", + "Latvian": "latvia", + "Lithuanian": "liettua", + "Luxembourgish": "luksemburgi", + "Macedonian": "makedonia", + "Malagasy": "malagassi", + "Malay": "malaiji", + "Malayalam": "malajalam", + "Maltese": "malta", + "Maori": "maori", + "Marathi": "marathi", + "Mongolian": "mongoli", + "Nepali": "nepali", + "Norwegian Bokmål": "kirjanorja", + "Nyanja": "njandža", + "Pashto": "paštu", + "Persian": "persia", + "Polish": "puola", + "Portuguese": "portugali", + "Punjabi": "pandžabi", + "Romanian": "romania", + "Russian": "venäjä", + "Samoan": "samoa", + "Scottish Gaelic": "gaeli", + "Serbian": "serbia", + "Shona": "šona", + "Sindhi": "sindhi", + "Sinhala": "sinhali", + "Slovak": "slovakki", + "Slovenian": "sloveeni", + "Somali": "somali", + "Southern Sotho": "eteläsotho", + "Spanish": "espanja", + "Spanish (Latin America)": "espanja (Latinalainen Amerikka)", + "Sundanese": "sunda", + "Swahili": "swahili", + "Swedish": "ruotsi", + "Tajik": "tadžikki", + "Tamil": "tamili", + "Telugu": "telugu", + "Thai": "thai", + "Turkish": "turkki", + "Ukrainian": "ukraina", + "Urdu": "urdu", + "Uzbek": "uzbekki", + "Vietnamese": "vietnam", + "Welsh": "kymri", + "Western Frisian": "länsifriisi", + "Xhosa": "xhosa", + "Yiddish": "jiddiš", + "Yoruba": "joruba", + "Zulu": "zulu", + "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "`x` vuotta.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` years.": "`x` vuotta.", + "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "`x` kuukautta.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` months.": "`x` kuukautta.", + "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "`x` viikkoa.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` weeks.": "`x` viikkoa.", + "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "`x` päivää.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` days.": "`x` päivää.", + "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tuntia.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` hours.": "`x` tuntia.", + "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "`x` minuuttia.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` minutes.": "`x` minuuttia.", + "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "`x` sekuntia.([^.,0-9]|^)1([^.,0-9]|$)", + "`x` seconds.": "`x` sekuntia.", + "Fallback comments: ": "varakommentit: ", + "Popular": "Suosittu", + "Top": "Ylin", + "About": "Tietoa", + "Rating: ": "Arvosana: ", + "Language: ": "Kieli: ", + "View as playlist": "Näytä soittolistana", + "Default": "Oletus", + "Music": "Musiikki", + "Gaming": "Videopelit", + "News": "Uutiset", + "Movies": "Elokuvat", + "Download": "Tallenna", + "Download as: ": "Tallennusmuoto: ", + "%A %B %-d, %Y": "%A %-d. %Bta, %Y", + "(edited)": "(muokattu)", + "YouTube comment permalink": "Pysyvä linkki YouTube-kommenttiin", + "permalink": "pysyvä linkki", + "`x` marked it with a ❤": "`x` merkattu ❤:llä", + "Audio mode": "Äänitila", + "Video mode": "Videotila", + "Videos": "Videot", + "Playlists": "Soittolistat", + "Community": "Yhteisö", + "Current version: ": "Tämänhetkinen versio: " } diff --git a/locales/hu-HU.json b/locales/hu-HU.json index b21ae93a..f60bb7d2 100644 --- a/locales/hu-HU.json +++ b/locales/hu-HU.json @@ -83,9 +83,9 @@ "published": "közzétéve", "published - reverse": "közzétéve (ford.)", "alphabetically": "ABC sorrend", - "alphabetically - reverse": "ABC sorrend (ford.)", + "alphabetically - reverse": "ABC sorrend (ford.)", "channel name": "csatorna neve", - "channel name - reverse": "csatorna neve (ford.)", + "channel name - reverse": "csatorna neve (ford.)", "Only show latest video from channel: ": "Csak a legutolsó videó mutatása a csatornából: ", "Only show latest unwatched video from channel: ": "Csak a legutolsó nem megtekintett videó mutatása a csatornából: ", "Only show unwatched: ": "Csak a nem megtekintettek mutatása: ", @@ -332,4 +332,4 @@ "Playlists": "Playlistek", "Community": "Közösség", "Current version: ": "Jelenlegi verzió: " -}
\ No newline at end of file +} diff --git a/locales/id.json b/locales/id.json index 217ea1c7..62577127 100644 --- a/locales/id.json +++ b/locales/id.json @@ -377,7 +377,7 @@ "(edited)": "(disunting)", "YouTube comment permalink": "", "permalink": "", - "`x` marked it with a ❤": "`x` telah ditandai dengan ❤", + "`x` marked it with a ❤": "`x` telah ditandai dengan ❤", "Audio mode": "Mode audio", "Video mode": "Mode video", "Videos": "Video", diff --git a/src/invidious.cr b/src/invidious.cr index b320d344..713d193e 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -30,11 +30,8 @@ require "./invidious/*" require "./invidious/routes/**" require "./invidious/jobs/**" -ENV_CONFIG_NAME = "INVIDIOUS_CONFIG" - -CONFIG_STR = ENV.has_key?(ENV_CONFIG_NAME) ? ENV.fetch(ENV_CONFIG_NAME) : File.read("config/config.yml") -CONFIG = Config.from_yaml(CONFIG_STR) -HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32) +CONFIG = Config.load +HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32) PG_URL = URI.new( scheme: "postgres", @@ -52,7 +49,7 @@ PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com") REDDIT_URL = URI.parse("https://www.reddit.com") TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com") YT_URL = URI.parse("https://www.youtube.com") -HOST_URL = make_host_url(CONFIG, Kemal.config) +HOST_URL = make_host_url(Kemal.config) CHARS_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk", "iqKdEhx-dD4"} @@ -85,6 +82,7 @@ LOCALES = { "eo" => load_locale("eo"), "es" => load_locale("es"), "fa" => load_locale("fa"), + "fi" => load_locale("fi"), "fr" => load_locale("fr"), "hr" => load_locale("hr"), "is" => load_locale("is"), @@ -145,8 +143,6 @@ end OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a") LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level) -config = CONFIG - # Check table integrity if CONFIG.check_tables check_enum(PG_DB, "privacy", PlaylistPrivacy) @@ -167,28 +163,33 @@ end # Start jobs -Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, config) -Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, config) +if CONFIG.channel_threads > 0 + Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB) +end + +if CONFIG.feed_threads > 0 + Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB) +end DECRYPT_FUNCTION = DecryptFunction.new(CONFIG.decrypt_polling) -if config.decrypt_polling +if CONFIG.decrypt_polling Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new end -if config.statistics_enabled - Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, config, SOFTWARE) +if CONFIG.statistics_enabled + Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, SOFTWARE) end -if (config.use_pubsub_feeds.is_a?(Bool) && config.use_pubsub_feeds.as(Bool)) || (config.use_pubsub_feeds.is_a?(Int32) && config.use_pubsub_feeds.as(Int32) > 0) - Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, config, HMAC_KEY) +if (CONFIG.use_pubsub_feeds.is_a?(Bool) && CONFIG.use_pubsub_feeds.as(Bool)) || (CONFIG.use_pubsub_feeds.is_a?(Int32) && CONFIG.use_pubsub_feeds.as(Int32) > 0) + Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, HMAC_KEY) end -if config.popular_enabled +if CONFIG.popular_enabled Invidious::Jobs.register Invidious::Jobs::PullPopularVideosJob.new(PG_DB) end -if config.captcha_key - Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new(config) +if CONFIG.captcha_key + Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new end connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32) @@ -219,7 +220,7 @@ before_all do |env| env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob:#{extra_media_csp}; child-src blob:" env.response.headers["Referrer-Policy"] = "same-origin" - if (Kemal.config.ssl || config.https_only) && config.hsts + if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload" end @@ -1164,7 +1165,7 @@ end get "/feed/popular" do |env| locale = LOCALES[env.get("preferences").as(Preferences).locale]? - if config.popular_enabled + if CONFIG.popular_enabled templated "popular" else message = translate(locale, "The Popular feed has been disabled by the administrator.") @@ -1822,7 +1823,7 @@ get "/api/v1/stats" do |env| locale = LOCALES[env.get("preferences").as(Preferences).locale]? env.response.content_type = "application/json" - if !config.statistics_enabled + if !CONFIG.statistics_enabled next error_json(400, "Statistics are not enabled.") end @@ -2232,7 +2233,7 @@ get "/api/v1/popular" do |env| env.response.content_type = "application/json" - if !config.popular_enabled + if !CONFIG.popular_enabled error_message = {"error" => "Administrator has disabled this endpoint."}.to_json env.response.status_code = 400 next error_message diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr index 2c62d44b..68ced430 100644 --- a/src/invidious/helpers/errors.cr +++ b/src/invidious/helpers/errors.cr @@ -7,7 +7,7 @@ class InfoException < Exception end macro error_template(*args) - error_template_helper(env, config, locale, {{*args}}) + error_template_helper(env, locale, {{*args}}) end def github_details(summary : String, content : String) @@ -22,9 +22,9 @@ def github_details(summary : String, content : String) return HTML.escape(details) end -def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) +def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) if exception.is_a?(InfoException) - return error_template_helper(env, config, locale, status_code, exception.message || "") + return error_template_helper(env, locale, status_code, exception.message || "") end env.response.content_type = "text/html" env.response.status_code = status_code @@ -43,7 +43,7 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale : return templated "error" end -def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) +def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) env.response.content_type = "text/html" env.response.status_code = status_code error_message = translate(locale, message) @@ -51,31 +51,31 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale : end macro error_atom(*args) - error_atom_helper(env, config, locale, {{*args}}) + error_atom_helper(env, locale, {{*args}}) end -def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) +def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) if exception.is_a?(InfoException) - return error_atom_helper(env, config, locale, status_code, exception.message || "") + return error_atom_helper(env, locale, status_code, exception.message || "") end env.response.content_type = "application/atom+xml" env.response.status_code = status_code return "<error>#{exception.inspect_with_backtrace}</error>" end -def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) +def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) env.response.content_type = "application/atom+xml" env.response.status_code = status_code return "<error>#{message}</error>" end macro error_json(*args) - error_json_helper(env, config, locale, {{*args}}) + error_json_helper(env, locale, {{*args}}) end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil) if exception.is_a?(InfoException) - return error_json_helper(env, config, locale, status_code, exception.message || "", additional_fields) + return error_json_helper(env, locale, status_code, exception.message || "", additional_fields) end env.response.content_type = "application/json" env.response.status_code = status_code @@ -86,11 +86,11 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has return error_message.to_json end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) - return error_json_helper(env, config, locale, status_code, exception, nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) + return error_json_helper(env, locale, status_code, exception, nil) end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil) env.response.content_type = "application/json" env.response.status_code = status_code error_message = {"error" => message} @@ -100,6 +100,6 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has return error_message.to_json end -def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) - error_json_helper(env, config, locale, status_code, message, nil) +def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String) + error_json_helper(env, locale, status_code, message, nil) end diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index 6bbb18cb..00087143 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -115,6 +115,63 @@ class Config return false end end + + def self.load + # Load config from file or YAML string env var + env_config_file = "INVIDIOUS_CONFIG_FILE" + env_config_yaml = "INVIDIOUS_CONFIG" + + config_file = ENV.has_key?(env_config_file) ? ENV.fetch(env_config_file) : "config/config.yml" + config_yaml = ENV.has_key?(env_config_yaml) ? ENV.fetch(env_config_yaml) : File.read(config_file) + + config = Config.from_yaml(config_yaml) + + # Update config from env vars (upcased and prefixed with "INVIDIOUS_") + {% for ivar in Config.instance_vars %} + {% env_id = "INVIDIOUS_#{ivar.id.upcase}" %} + + if ENV.has_key?({{env_id}}) + # puts %(Config.{{ivar.id}} : Loading from env var {{env_id}}) + env_value = ENV.fetch({{env_id}}) + success = false + + # Use YAML converter if specified + {% ann = ivar.annotation(::YAML::Field) %} + {% if ann && ann[:converter] %} + puts %(Config.{{ivar.id}} : Parsing "#{env_value}" as {{ivar.type}} with {{ann[:converter]}} converter) + config.{{ivar.id}} = {{ann[:converter]}}.from_yaml(YAML::ParseContext.new, YAML::Nodes.parse(ENV.fetch({{env_id}})).nodes[0]) + puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}}) + success = true + + # Use regular YAML parser otherwise + {% else %} + {% ivar_types = ivar.type.union? ? ivar.type.union_types : [ivar.type] %} + # Sort types to avoid parsing nulls and numbers as strings + {% ivar_types = ivar_types.sort_by { |ivar_type| ivar_type == Nil ? 0 : ivar_type == Int32 ? 1 : 2 } %} + {{ivar_types}}.each do |ivar_type| + if !success + begin + # puts %(Config.{{ivar.id}} : Trying to parse "#{env_value}" as #{ivar_type}) + config.{{ivar.id}} = ivar_type.from_yaml(env_value) + puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}} (#{ivar_type})) + success = true + rescue + # nop + end + end + end + {% end %} + + # Exit on fail + if !success + puts %(Config.{{ivar.id}} failed to parse #{env_value} as {{ivar.type}}) + exit(1) + end + end + {% end %} + + return config + end end struct DBConfig diff --git a/src/invidious/helpers/logger.cr b/src/invidious/helpers/logger.cr index 7c5b0247..5d91a258 100644 --- a/src/invidious/helpers/logger.cr +++ b/src/invidious/helpers/logger.cr @@ -1,5 +1,3 @@ -require "logger" - enum LogLevel All = 0 Trace = 1 diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index f068b5f2..7d94a6e5 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -280,9 +280,9 @@ def arg_array(array, start = 1) return args end -def make_host_url(config, kemal_config) - ssl = config.https_only || kemal_config.ssl - port = config.external_port || kemal_config.port +def make_host_url(kemal_config) + ssl = CONFIG.https_only || kemal_config.ssl + port = CONFIG.external_port || kemal_config.port if ssl scheme = "https://" @@ -297,11 +297,11 @@ def make_host_url(config, kemal_config) port = "" end - if !config.domain + if !CONFIG.domain return "" end - host = config.domain.not_nil!.lchop(".") + host = CONFIG.domain.not_nil!.lchop(".") return "#{scheme}#{host}#{port}" end @@ -345,7 +345,7 @@ def sha256(text) return digest.final.hexstring end -def subscribe_pubsub(topic, key, config) +def subscribe_pubsub(topic, key) case topic when .match(/^UC[A-Za-z0-9_-]{22}$/) topic = "channel_id=#{topic}" diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr index 22c54036..8b1aed5f 100644 --- a/src/invidious/jobs/bypass_captcha_job.cr +++ b/src/invidious/jobs/bypass_captcha_job.cr @@ -1,9 +1,4 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob - private getter config : Config - - def initialize(@config) - end - def begin loop do begin @@ -22,9 +17,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob headers = response.cookies.add_request_headers(HTTP::Headers.new) - response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/createTask", + response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/createTask", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "task" => { "type" => "NoCaptchaTaskProxyless", "websiteURL" => "https://www.youtube.com#{path}", @@ -39,9 +34,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob loop do sleep 10.seconds - response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/getTaskResult", + response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/getTaskResult", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "taskId" => task_id, }.to_json).body) @@ -58,10 +53,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob response.cookies .select { |cookie| cookie.name != "PREF" } - .each { |cookie| config.cookies << cookie } + .each { |cookie| CONFIG.cookies << cookie } # Persist cookies between runs - File.write("config/config.yml", config.to_yaml) + File.write("config/config.yml", CONFIG.to_yaml) elsif response.headers["Location"]?.try &.includes?("/sorry/index") location = response.headers["Location"].try { |u| URI.parse(u) } headers = HTTP::Headers{":authority" => location.host.not_nil!} @@ -77,11 +72,11 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob inputs[node["name"]] = node["value"] end - captcha_client = HTTPClient.new(URI.parse(config.captcha_api_url)) - captcha_client.family = config.force_resolve || Socket::Family::INET + captcha_client = HTTPClient.new(URI.parse(CONFIG.captcha_api_url)) + captcha_client.family = CONFIG.force_resolve || Socket::Family::INET response = JSON.parse(captcha_client.post("/createTask", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "task" => { "type" => "NoCaptchaTaskProxyless", "websiteURL" => location.to_s, @@ -100,7 +95,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob response = JSON.parse(captcha_client.post("/getTaskResult", headers: HTTP::Headers{"Content-Type" => "application/json"}, body: { - "clientKey" => config.captcha_key, + "clientKey" => CONFIG.captcha_key, "taskId" => task_id, }.to_json).body) @@ -119,10 +114,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob } cookies = HTTP::Cookies.from_headers(headers) - cookies.each { |cookie| config.cookies << cookie } + cookies.each { |cookie| CONFIG.cookies << cookie } # Persist cookies between runs - File.write("config/config.yml", config.to_yaml) + File.write("config/config.yml", CONFIG.to_yaml) end end rescue ex diff --git a/src/invidious/jobs/refresh_channels_job.cr b/src/invidious/jobs/refresh_channels_job.cr index 3e94a56e..fbe6d381 100644 --- a/src/invidious/jobs/refresh_channels_job.cr +++ b/src/invidious/jobs/refresh_channels_job.cr @@ -1,12 +1,11 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob private getter db : DB::Database - private getter config : Config - def initialize(@db, @config) + def initialize(@db) end def begin - max_fibers = config.channel_threads + max_fibers = CONFIG.channel_threads lim_fibers = max_fibers active_fibers = 0 active_channel = Channel(Bool).new @@ -31,7 +30,7 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob spawn do begin LOGGER.trace("RefreshChannelsJob: #{id} fiber : Fetching channel") - channel = fetch_channel(id, db, config.full_refresh) + channel = fetch_channel(id, db, CONFIG.full_refresh) lim_fibers = max_fibers diff --git a/src/invidious/jobs/refresh_feeds_job.cr b/src/invidious/jobs/refresh_feeds_job.cr index 7b4ccdea..926c27fa 100644 --- a/src/invidious/jobs/refresh_feeds_job.cr +++ b/src/invidious/jobs/refresh_feeds_job.cr @@ -1,12 +1,11 @@ class Invidious::Jobs::RefreshFeedsJob < Invidious::Jobs::BaseJob private getter db : DB::Database - private getter config : Config - def initialize(@db, @config) + def initialize(@db) end def begin - max_fibers = config.feed_threads + max_fibers = CONFIG.feed_threads active_fibers = 0 active_channel = Channel(Bool).new diff --git a/src/invidious/jobs/statistics_refresh_job.cr b/src/invidious/jobs/statistics_refresh_job.cr index 021671be..aa46fb0e 100644 --- a/src/invidious/jobs/statistics_refresh_job.cr +++ b/src/invidious/jobs/statistics_refresh_job.cr @@ -21,9 +21,8 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob } private getter db : DB::Database - private getter config : Config - def initialize(@db, @config, @software_config : Hash(String, String)) + def initialize(@db, @software_config : Hash(String, String)) end def begin @@ -43,7 +42,7 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob "version" => @software_config["version"], "branch" => @software_config["branch"], } - STATISTICS["openRegistration"] = config.registration_enabled + STATISTICS["openRegistration"] = CONFIG.registration_enabled end private def refresh_stats diff --git a/src/invidious/jobs/subscribe_to_feeds_job.cr b/src/invidious/jobs/subscribe_to_feeds_job.cr index 750aceb8..a431a48a 100644 --- a/src/invidious/jobs/subscribe_to_feeds_job.cr +++ b/src/invidious/jobs/subscribe_to_feeds_job.cr @@ -1,15 +1,14 @@ class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob private getter db : DB::Database private getter hmac_key : String - private getter config : Config - def initialize(@db, @config, @hmac_key) + def initialize(@db, @hmac_key) end def begin max_fibers = 1 - if config.use_pubsub_feeds.is_a?(Int32) - max_fibers = config.use_pubsub_feeds.as(Int32) + if CONFIG.use_pubsub_feeds.is_a?(Int32) + max_fibers = CONFIG.use_pubsub_feeds.as(Int32) end active_fibers = 0 @@ -30,7 +29,7 @@ class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob spawn do begin - response = subscribe_pubsub(ucid, hmac_key, config) + response = subscribe_pubsub(ucid, hmac_key) if response.status_code >= 400 LOGGER.error("SubscribeToFeedsJob: #{ucid} : #{response.body}") diff --git a/src/invidious/routes/base_route.cr b/src/invidious/routes/base_route.cr index 37624267..07c6f15b 100644 --- a/src/invidious/routes/base_route.cr +++ b/src/invidious/routes/base_route.cr @@ -1,6 +1,2 @@ abstract class Invidious::Routes::BaseRoute - private getter config : Config - - def initialize(@config) - end end diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr index 45a6d4d8..662fdf13 100644 --- a/src/invidious/routes/login.cr +++ b/src/invidious/routes/login.cr @@ -6,7 +6,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute return env.redirect "/feed/subscriptions" if user - if !config.login_enabled + if !CONFIG.login_enabled return error_template(400, "Login has been disabled by administrator.") end @@ -33,7 +33,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute referer = get_referer(env, "/feed/subscriptions") - if !config.login_enabled + if !CONFIG.login_enabled return error_template(403, "Login has been disabled by administrator.") end @@ -274,14 +274,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute host = URI.parse(env.request.headers["Host"]).host - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end cookies.each do |cookie| - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only cookie.secure = secure else cookie.secure = secure @@ -330,14 +330,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32)) PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", sid, email, Time.utc) - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years, @@ -354,7 +354,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute env.response.cookies << cookie end else - if !config.registration_enabled + if !CONFIG.registration_enabled return error_template(400, "Registration has been disabled by administrator.") end @@ -369,7 +369,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute password = password.byte_slice(0, 55) - if config.captcha_enabled + if CONFIG.captcha_enabled captcha_type = env.params.body["captcha_type"]? answer = env.params.body["answer"]? change_type = env.params.body["change_type"]? @@ -445,14 +445,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute view_name = "subscriptions_#{sha256(user.email)}" PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}") - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years, diff --git a/src/invidious/routes/user_preferences.cr b/src/invidious/routes/user_preferences.cr index 7f334115..a689a2a2 100644 --- a/src/invidious/routes/user_preferences.cr +++ b/src/invidious/routes/user_preferences.cr @@ -146,8 +146,8 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute user = user.as(User) PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email) - if config.admins.includes? user.email - config.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || config.default_user_preferences.default_home + if CONFIG.admins.includes? user.email + CONFIG.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || CONFIG.default_user_preferences.default_home admin_feed_menu = [] of String 4.times do |index| @@ -156,40 +156,39 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute admin_feed_menu << option end end - config.default_user_preferences.feed_menu = admin_feed_menu + CONFIG.default_user_preferences.feed_menu = admin_feed_menu popular_enabled = env.params.body["popular_enabled"]?.try &.as(String) popular_enabled ||= "off" - config.popular_enabled = popular_enabled == "on" + CONFIG.popular_enabled = popular_enabled == "on" captcha_enabled = env.params.body["captcha_enabled"]?.try &.as(String) captcha_enabled ||= "off" - config.captcha_enabled = captcha_enabled == "on" + CONFIG.captcha_enabled = captcha_enabled == "on" login_enabled = env.params.body["login_enabled"]?.try &.as(String) login_enabled ||= "off" - config.login_enabled = login_enabled == "on" + CONFIG.login_enabled = login_enabled == "on" registration_enabled = env.params.body["registration_enabled"]?.try &.as(String) registration_enabled ||= "off" - config.registration_enabled = registration_enabled == "on" + CONFIG.registration_enabled = registration_enabled == "on" statistics_enabled = env.params.body["statistics_enabled"]?.try &.as(String) statistics_enabled ||= "off" - config.statistics_enabled = statistics_enabled == "on" + CONFIG.statistics_enabled = statistics_enabled == "on" - CONFIG.default_user_preferences = config.default_user_preferences - File.write("config/config.yml", config.to_yaml) + File.write("config/config.yml", CONFIG.to_yaml) end else - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years, @@ -234,14 +233,14 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute preferences = preferences.to_json - if Kemal.config.ssl || config.https_only + if Kemal.config.ssl || CONFIG.https_only secure = true else secure = false end - if config.domain - env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years, + if CONFIG.domain + env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years, secure: secure, http_only: true) else env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years, diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 593c7372..82d0028b 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -1,14 +1,14 @@ module Invidious::Routing macro get(path, controller, method = :handle) get {{ path }} do |env| - controller_instance = {{ controller }}.new(config) + controller_instance = {{ controller }}.new controller_instance.{{ method.id }}(env) end end macro post(path, controller, method = :handle) post {{ path }} do |env| - controller_instance = {{ controller }}.new(config) + controller_instance = {{ controller }}.new controller_instance.{{ method.id }}(env) end end diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr index 1ef080be..14d63536 100644 --- a/src/invidious/views/preferences.ecr +++ b/src/invidious/views/preferences.ecr @@ -208,14 +208,14 @@ </div> <% # Web notifications are only supported over HTTPS %> - <% if Kemal.config.ssl || config.https_only %> + <% if Kemal.config.ssl || CONFIG.https_only %> <div class="pure-control-group"> <a href="#" data-onclick="notification_requestPermission"><%= translate(locale, "Enable web notifications") %></a> </div> <% end %> <% end %> - <% if env.get?("user") && config.admins.includes? env.get?("user").as(User).email %> + <% if env.get?("user") && CONFIG.admins.includes? env.get?("user").as(User).email %> <legend><%= translate(locale, "Administrator preferences") %></legend> <div class="pure-control-group"> @@ -240,28 +240,28 @@ <div class="pure-control-group"> <label for="popular_enabled"><%= translate(locale, "Popular enabled: ") %></label> - <input name="popular_enabled" id="popular_enabled" type="checkbox" <% if config.popular_enabled %>checked<% end %>> + <input name="popular_enabled" id="popular_enabled" type="checkbox" <% if CONFIG.popular_enabled %>checked<% end %>> </div> <div class="pure-control-group"> <label for="captcha_enabled"><%= translate(locale, "CAPTCHA enabled: ") %></label> - <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if config.captcha_enabled %>checked<% end %>> + <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if CONFIG.captcha_enabled %>checked<% end %>> </div> <div class="pure-control-group"> <label for="login_enabled"><%= translate(locale, "Login enabled: ") %></label> - <input name="login_enabled" id="login_enabled" type="checkbox" <% if config.login_enabled %>checked<% end %>> + <input name="login_enabled" id="login_enabled" type="checkbox" <% if CONFIG.login_enabled %>checked<% end %>> </div> <div class="pure-control-group"> <label for="registration_enabled"><%= translate(locale, "Registration enabled: ") %></label> - <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if config.registration_enabled %>checked<% end %>> + <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if CONFIG.registration_enabled %>checked<% end %>> </div> <div class="pure-control-group"> <label for="statistics_enabled"><%= translate(locale, "Report statistics: ") %></label> - <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if config.statistics_enabled %>checked<% end %>> + <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if CONFIG.statistics_enabled %>checked<% end %>> </div> <% end %> diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr index f6e5262d..61b900e3 100644 --- a/src/invidious/views/template.ecr +++ b/src/invidious/views/template.ecr @@ -87,7 +87,7 @@ <i class="icon ion-ios-cog"></i> </a> </div> - <% if config.login_enabled %> + <% if CONFIG.login_enabled %> <div class="pure-u-1-3"> <a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading"> <%= translate(locale, "Log in") %> |
