diff --git a/.all-contributorsrc b/.all-contributorsrc index 3cf5e765c5..5a1ddadd59 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -737,6 +737,177 @@ "contributions": [ "translation" ] + }, + { + "login": "Eclipseop", + "name": "Mackenzie", + "avatar_url": "https://avatars.githubusercontent.com/u/5846213?v=4", + "profile": "https://github.com/Eclipseop", + "contributions": [ + "code" + ] + }, + { + "login": "s0up4200", + "name": "soup", + "avatar_url": "https://avatars.githubusercontent.com/u/18177310?v=4", + "profile": "https://github.com/s0up4200", + "contributions": [ + "doc" + ] + }, + { + "login": "ceptonit", + "name": "ceptonit", + "avatar_url": "https://avatars.githubusercontent.com/u/12678743?v=4", + "profile": "https://github.com/ceptonit", + "contributions": [ + "doc" + ] + }, + { + "login": "aedelbro", + "name": "aedelbro", + "avatar_url": "https://avatars.githubusercontent.com/u/36162221?v=4", + "profile": "https://github.com/aedelbro", + "contributions": [ + "code" + ] + }, + { + "login": "lunks", + "name": "Pedro Nascimento", + "avatar_url": "https://avatars.githubusercontent.com/u/91118?v=4", + "profile": "http://twitter.com/lunks/", + "contributions": [ + "code" + ] + }, + { + "login": "owenvoke", + "name": "Owen Voke", + "avatar_url": "https://avatars.githubusercontent.com/u/1899334?v=4", + "profile": "https://voke.dev", + "contributions": [ + "code" + ] + }, + { + "login": "Nimelrian", + "name": "Sebastian K", + "avatar_url": "https://avatars.githubusercontent.com/u/8960836?v=4", + "profile": "https://github.com/Nimelrian", + "contributions": [ + "code" + ] + }, + { + "login": "jariz", + "name": "jariz", + "avatar_url": "https://avatars.githubusercontent.com/u/1415847?v=4", + "profile": "https://github.com/jariz", + "contributions": [ + "code" + ] + }, + { + "login": "Alexays", + "name": "Alex", + "avatar_url": "https://avatars.githubusercontent.com/u/13947260?v=4", + "profile": "https://arouillard.fr", + "contributions": [ + "code" + ] + }, + { + "login": "Zebebles", + "name": "Zeb Muller", + "avatar_url": "https://avatars.githubusercontent.com/u/11425451?v=4", + "profile": "https://github.com/Zebebles", + "contributions": [ + "code" + ] + }, + { + "login": "SMores", + "name": "Shane Friedman", + "avatar_url": "https://avatars.githubusercontent.com/u/5354254?v=4", + "profile": "http://smoores.dev", + "contributions": [ + "code" + ] + }, + { + "login": "IzaacJ", + "name": "Izaac Brånn", + "avatar_url": "https://avatars.githubusercontent.com/u/711323?v=4", + "profile": "https://izaacj.me", + "contributions": [ + "code" + ] + }, + { + "login": "SalmanTariq", + "name": "Salman Tariq", + "avatar_url": "https://avatars.githubusercontent.com/u/13284494?v=4", + "profile": "https://github.com/SalmanTariq", + "contributions": [ + "code" + ] + }, + { + "login": "andrew-kennedy", + "name": "Andrew Kennedy", + "avatar_url": "https://avatars.githubusercontent.com/u/2387159?v=4", + "profile": "https://github.com/andrew-kennedy", + "contributions": [ + "code" + ] + }, + { + "login": "Fallenbagel", + "name": "Fallenbagel", + "avatar_url": "https://avatars.githubusercontent.com/u/98979876?v=4", + "profile": "https://github.com/Fallenbagel", + "contributions": [ + "code" + ] + }, + { + "login": "scorp200", + "name": "Anton K. (ai Doge)", + "avatar_url": "https://avatars.githubusercontent.com/u/9427639?v=4", + "profile": "http://aidoge.xyz", + "contributions": [ + "code" + ] + }, + { + "login": "marcofaggian", + "name": "Marco Faggian", + "avatar_url": "https://avatars.githubusercontent.com/u/19221001?v=4", + "profile": "https://marcofaggian.com", + "contributions": [ + "code" + ] + }, + { + "login": "nemchik", + "name": "Eric Nemchik", + "avatar_url": "https://avatars.githubusercontent.com/u/725456?v=4", + "profile": "http://nemchik.com/", + "contributions": [ + "code" + ] + }, + { + "login": "RemiRigal", + "name": "RemiRigal", + "avatar_url": "https://avatars.githubusercontent.com/u/19256051?v=4", + "profile": "https://github.com/RemiRigal", + "contributions": [ + "code" + ] } ], "badgeTemplate": "\"All-orange.svg\"/>", @@ -745,5 +916,7 @@ "projectOwner": "sct", "repoType": "github", "repoHost": "https://github.com", - "skipCi": false + "skipCi": false, + "commitConvention": "angular", + "commitType": "docs" } diff --git a/.gitattributes b/.gitattributes index 2883a5d26f..eb5d2314fc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -24,3 +24,24 @@ *.woff binary *.pyc binary *.pdf binary + +# +## Theses files/directories should be excluded from git archives +# + +.husky export-ignore +.vscode export-ignore +docs export-ignore + +.git* export-ignore +*ignore export-ignore +*.md export-ignore + +.all-contributorsrc export-ignore +.editorconfig export-ignore +Dockerfile.local export-ignore +docker-compose.yml export-ignore +stylelint.config.js export-ignore + +public/os_logo_filled.png export-ignore +public/preview.jpg export-ignore diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6effae045d..68a2d018e8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,10 +1,10 @@ # Global code ownership -* @sct @TheCatLady @danshilm +* @sct @TheCatLady @danshilm @OwsleyJr # Documentation -/.all-contributorsrc @TheCatLady @samwiseg0 @danshilm -/*.md @TheCatLady @samwiseg0 @danshilm -/docs/ @TheCatLady @samwiseg0 @danshilm +/.all-contributorsrc @TheCatLady @samwiseg0 @danshilm @OwsleyJr +/*.md @TheCatLady @samwiseg0 @danshilm @OwsleyJr +/docs/ @TheCatLady @samwiseg0 @danshilm @OwsleyJr # Snap-related files /.github/workflows/snap.yaml @samwiseg0 @@ -12,4 +12,4 @@ # i18n locale files /src/i18n/locale/ @sct @TheCatLady -/src/i18n/locale/en.json @sct @TheCatLady @danshilm +/src/i18n/locale/en.json @sct @TheCatLady @danshilm @OwsleyJr diff --git a/.github/holopin.yml b/.github/holopin.yml new file mode 100644 index 0000000000..ee4edc81b3 --- /dev/null +++ b/.github/holopin.yml @@ -0,0 +1,5 @@ +organization: overseerr +defaultSticker: clcyagj1j329008l468ya8pu2 +stickers: + - id: clcyagj1j329008l468ya8pu2 + alias: overseerr-contributor diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05db03e1bd..2be6b2e050 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ jobs: test: name: Lint & Test Build if: github.event_name == 'pull_request' - runs-on: ubuntu-20.04 - container: node:16.17-alpine + runs-on: ubuntu-22.04 + container: node:18.18-alpine steps: - name: Checkout uses: actions/checkout@v3 @@ -31,7 +31,7 @@ jobs: build_and_push: name: Build & Publish Docker Images if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]') - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v3 @@ -39,13 +39,6 @@ jobs: uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Cache Docker layers - uses: actions/cache@v3 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - name: Log in to Docker Hub uses: docker/login-action@v2 with: @@ -71,21 +64,12 @@ jobs: sctx/overseerr:${{ github.sha }} ghcr.io/sct/overseerr:develop ghcr.io/sct/overseerr:${{ github.sha }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - - # Temporary fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache discord: name: Send Discord Notification needs: build_and_push if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]') - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Get Build Job Status uses: technote-space/workflow-conclusion-action@v3 @@ -94,9 +78,9 @@ jobs: run: | failures=(neutral, skipped, timed_out, action_required) if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then - echo ::set-output name=status::failure + echo "status=failure" >> $GITHUB_OUTPUT else - echo ::set-output name=status::$WORKFLOW_CONCLUSION + echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT fi - name: Post Status to Discord uses: sarisia/actions-status-discord@v1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..10926bbd92 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: 'CodeQL' + +on: + push: + branches: ['develop'] + pull_request: + branches: ['develop'] + schedule: + - cron: '50 7 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [javascript] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 6e0d8f3d89..330644290f 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -8,13 +8,13 @@ on: jobs: build_and_push: name: Build & Publish Docker Preview Images - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v3 - name: Get the version id: get_version - run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/} + run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 839b2245c8..806d51bf07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ on: jobs: semantic-release: name: Tag and release latest version - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v3 @@ -45,7 +45,7 @@ jobs: build-snap: name: Build Snap Package (${{ matrix.architecture }}) needs: semantic-release - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -67,9 +67,9 @@ jobs: run: | git fetch --prune --tags if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then - echo ::set-output name=RELEASE::stable + echo "RELEASE=stable" >> $GITHUB_OUTPUT else - echo ::set-output name=RELEASE::edge + echo "RELEASE=edge" >> $GITHUB_OUTPUT fi - name: Set Up QEMU uses: docker/setup-qemu-action@v2 @@ -91,8 +91,9 @@ jobs: snap: ${{ steps.build.outputs.snap }} - name: Publish Snap Package uses: snapcore/action-publish@v1 + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }} with: - store_login: ${{ secrets.SNAP_LOGIN }} snap: ${{ steps.build.outputs.snap }} release: ${{ steps.prepare.outputs.RELEASE }} @@ -100,7 +101,7 @@ jobs: name: Send Discord Notification needs: semantic-release if: always() - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Get Build Job Status uses: technote-space/workflow-conclusion-action@v3 @@ -109,9 +110,9 @@ jobs: run: | failures=(neutral, skipped, timed_out, action_required) if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then - echo ::set-output name=status::failure + echo "status=failure" >> $GITHUB_OUTPUT else - echo ::set-output name=status::$WORKFLOW_CONCLUSION + echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT fi - name: Post Status to Discord uses: sarisia/actions-status-discord@v1 diff --git a/.github/workflows/snap.yaml b/.github/workflows/snap.yaml index bf00e04d7d..16489a8996 100644 --- a/.github/workflows/snap.yaml +++ b/.github/workflows/snap.yaml @@ -8,7 +8,7 @@ on: jobs: jobs: name: Job Check - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: "!contains(github.event.head_commit.message, '[skip ci]')" steps: - name: Cancel Previous Runs @@ -19,7 +19,7 @@ jobs: build-snap: name: Build Snap Package (${{ matrix.architecture }}) needs: jobs - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -35,9 +35,9 @@ jobs: run: | git fetch --prune --unshallow --tags if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then - echo ::set-output name=RELEASE::stable + echo "RELEASE=stable" >> $GITHUB_OUTPUT else - echo ::set-output name=RELEASE::edge + echo "RELEASE=edge" >> $GITHUB_OUTPUT fi - name: Set Up QEMU uses: docker/setup-qemu-action@v2 @@ -57,8 +57,9 @@ jobs: snap: ${{ steps.build.outputs.snap }} - name: Publish Snap Package uses: snapcore/action-publish@v1 + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }} with: - store_login: ${{ secrets.SNAP_LOGIN }} snap: ${{ steps.build.outputs.snap }} release: ${{ steps.prepare.outputs.RELEASE }} @@ -66,7 +67,7 @@ jobs: name: Send Discord Notification needs: build-snap if: always() && !contains(github.event.head_commit.message, '[skip ci]') - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Get Build Job Status uses: technote-space/workflow-conclusion-action@v3 @@ -75,9 +76,9 @@ jobs: run: | failures=(neutral, skipped, timed_out, action_required) if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then - echo ::set-output name=status::failure + echo "status=failure" >> $GITHUB_OUTPUT else - echo ::set-output name=status::$WORKFLOW_CONCLUSION + echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT fi - name: Post Status to Discord uses: sarisia/actions-status-discord@v1 diff --git a/.gitignore b/.gitignore index 4f7c3ce6cb..6e051447e8 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,6 @@ cypress/screenshots # TS Build Info tsconfig.tsbuildinfo + +# Config Cache Directory +config/cache diff --git a/.vscode/settings.json b/.vscode/settings.json index 45da7ba676..1a23757129 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,5 +16,8 @@ } ], "editor.formatOnSave": true, - "typescript.preferences.importModuleSpecifier": "non-relative" + "typescript.preferences.importModuleSpecifier": "non-relative", + "files.associations": { + "globals.css": "tailwindcss" + } } diff --git a/Dockerfile b/Dockerfile index 851ba47216..949bf59628 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16.17-alpine AS BUILD_IMAGE +FROM node:18.18-alpine AS BUILD_IMAGE WORKDIR /app @@ -7,10 +7,11 @@ ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} RUN \ case "${TARGETPLATFORM}" in \ - 'linux/arm64' | 'linux/arm/v7') \ - apk add --no-cache python3 make g++ && \ - ln -s /usr/bin/python3 /usr/bin/python \ - ;; \ + 'linux/arm64' | 'linux/arm/v7') \ + apk update && \ + apk add --no-cache python3 make g++ gcc libc6-compat bash && \ + yarn global add node-gyp \ + ;; \ esac COPY package.json yarn.lock ./ @@ -33,7 +34,7 @@ RUN touch config/DOCKER RUN echo "{\"commitTag\": \"${COMMIT_TAG}\"}" > committag.json -FROM node:16.17-alpine +FROM node:18.18-alpine WORKDIR /app diff --git a/Dockerfile.local b/Dockerfile.local index 39e0534f32..7efa68b51d 100644 --- a/Dockerfile.local +++ b/Dockerfile.local @@ -1,4 +1,4 @@ -FROM node:16.17-alpine +FROM node:18.18-alpine COPY . /app WORKDIR /app diff --git a/README.md b/README.md index 05de02e235..b5fa8824be 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,9 @@ Discord Docker pulls Translation status -Language grade: JavaScript GitHub -All Contributors +All Contributors

@@ -74,110 +73,137 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

sct

💻 🎨 🤔

Alex Zoitos

💻

Brandon Cohen

💻 📖

Ahreluth

🌍

KovalevArtem

🌍

GiyomuWeb

🌍

Angry Cuban

📖

jvennik

🌍

darknessgp

💻

salty

🚇

Shutruk

🌍

Krystian Charubin

🎨

Kieron Boswell

💻

samwiseg0

💬 🚇

ecelebi29

💻 📖

Mārtiņš Možeiko

💻

mazzetta86

🌍

Paul Hagedorn

🌍

Shagon94

🌍

sebstrgg

🌍

Danshil Mungur

💻 📖

doob187

🚇

johnpyp

💻

Jakob Ankarhem

📖 💻 🌍

Jayesh

💻

flying-sausages

📖

hirenshah

📖

TheCatLady

💻 🌍 📖

Chris Pritchard

💻 📖

Tamberlox

🌍

David

💻

Douglas Parker

📖

Daniel Carter

💻

nuro

📖

ᗪєνιη ᗷυнʟ

🚇

JonnyWong16

📖

Roxedus

📖

WoisWoi

🌍

HubDuck

🌍 📖

costaht

📖 🌍

Shjosan

🌍

kobaubarr

🌍

Ricardo González

🌍

Torkil

🌍

Jagandeep Brar

📖

dtalens

🌍

Alex Cortelyou

💻

Jono Cairns

💻

DJScias

🌍

Dabu-dot

🌍

Jabster28

💻

littlerooster

🌍

Dustin Hildebrandt

💻

Bruno Guerreiro

🌍

Alexander Neuhäuser

🌍

Livio

🎨

tangentThought

💻

Nicolás Espinoza

💻

sootylunatic

🌍

JoKerIsCraZy

🌍

Daddie0

🌍

Simone

🌍

Seohyun Joo

🌍

Sergey

🌍

Shaaft

🌍

sr093906

🌍

Nackophilz

🌍

Sean Chambers

💻

deniscerri

🌍

tomgacz

🌍

Andersborrits

🌍

Maxent

🌍

Samuel Bartík

💻

Chun Yeung Wong

💻

TheMeanCanEHdian

💻

Gylesie

💻

Fhd-pro

🌍

PovilasID

🌍

byakurau

🌍

miknii

🌍
sct
sct

💻 🎨 🤔
Alex Zoitos
Alex Zoitos

💻
Brandon Cohen
Brandon Cohen

💻 📖
Ahreluth
Ahreluth

🌍
KovalevArtem
KovalevArtem

🌍
GiyomuWeb
GiyomuWeb

🌍
Angry Cuban
Angry Cuban

📖
jvennik
jvennik

🌍
darknessgp
darknessgp

💻
salty
salty

🚇
Shutruk
Shutruk

🌍
Krystian Charubin
Krystian Charubin

🎨
Kieron Boswell
Kieron Boswell

💻
samwiseg0
samwiseg0

💬 🚇
ecelebi29
ecelebi29

💻 📖
Mārtiņš Možeiko
Mārtiņš Možeiko

💻
mazzetta86
mazzetta86

🌍
Paul Hagedorn
Paul Hagedorn

🌍
Shagon94
Shagon94

🌍
sebstrgg
sebstrgg

🌍
Danshil Mungur
Danshil Mungur

💻 📖
doob187
doob187

🚇
johnpyp
johnpyp

💻
Jakob Ankarhem
Jakob Ankarhem

📖 💻 🌍
Jayesh
Jayesh

💻
flying-sausages
flying-sausages

📖
hirenshah
hirenshah

📖
TheCatLady
TheCatLady

💻 🌍 📖
Chris Pritchard
Chris Pritchard

💻 📖
Tamberlox
Tamberlox

🌍
David
David

💻
Douglas Parker
Douglas Parker

📖
Daniel Carter
Daniel Carter

💻
nuro
nuro

📖
ᗪєνιη ᗷυнʟ
ᗪєνιη ᗷυнʟ

🚇
JonnyWong16
JonnyWong16

📖
Roxedus
Roxedus

📖
WoisWoi
WoisWoi

🌍
HubDuck
HubDuck

🌍 📖
costaht
costaht

📖 🌍
Shjosan
Shjosan

🌍
kobaubarr
kobaubarr

🌍
Ricardo González
Ricardo González

🌍
Torkil
Torkil

🌍
Jagandeep Brar
Jagandeep Brar

📖
dtalens
dtalens

🌍
Alex Cortelyou
Alex Cortelyou

💻
Jono Cairns
Jono Cairns

💻
DJScias
DJScias

🌍
Dabu-dot
Dabu-dot

🌍
Jabster28
Jabster28

💻
littlerooster
littlerooster

🌍
Dustin Hildebrandt
Dustin Hildebrandt

💻
Bruno Guerreiro
Bruno Guerreiro

🌍
Alexander Neuhäuser
Alexander Neuhäuser

🌍
Livio
Livio

🎨
tangentThought
tangentThought

💻
Nicolás Espinoza
Nicolás Espinoza

💻
sootylunatic
sootylunatic

🌍
JoKerIsCraZy
JoKerIsCraZy

🌍
Daddie0
Daddie0

🌍
Simone
Simone

🌍
Seohyun Joo
Seohyun Joo

🌍
Sergey
Sergey

🌍
Shaaft
Shaaft

🌍
sr093906
sr093906

🌍
Nackophilz
Nackophilz

🌍
Sean Chambers
Sean Chambers

💻
deniscerri
deniscerri

🌍
tomgacz
tomgacz

🌍
Andersborrits
Andersborrits

🌍
Maxent
Maxent

🌍
Samuel Bartík
Samuel Bartík

💻
Chun Yeung Wong
Chun Yeung Wong

💻
TheMeanCanEHdian
TheMeanCanEHdian

💻
Gylesie
Gylesie

💻
Fhd-pro
Fhd-pro

🌍
PovilasID
PovilasID

🌍
byakurau
byakurau

🌍
miknii
miknii

🌍
Mackenzie
Mackenzie

💻
soup
soup

📖
ceptonit
ceptonit

📖
aedelbro
aedelbro

💻
Pedro Nascimento
Pedro Nascimento

💻
Owen Voke
Owen Voke

💻
Sebastian K
Sebastian K

💻
jariz
jariz

💻
Alex
Alex

💻
Zeb Muller
Zeb Muller

💻
Shane Friedman
Shane Friedman

💻
Izaac Brånn
Izaac Brånn

💻
Salman Tariq
Salman Tariq

💻
Andrew Kennedy
Andrew Kennedy

💻
Fallenbagel
Fallenbagel

💻
Anton K. (ai Doge)
Anton K. (ai Doge)

💻
Marco Faggian
Marco Faggian

💻
Eric Nemchik
Eric Nemchik

💻
RemiRigal
RemiRigal

💻
diff --git a/cypress/config/settings.cypress.json b/cypress/config/settings.cypress.json index bb7b661b0a..7a4bbef5d6 100644 --- a/cypress/config/settings.cypress.json +++ b/cypress/config/settings.cypress.json @@ -3,147 +3,147 @@ "vapidPrivate": "tmnslaO8ZWN6bNbSEv_rolPeBTlNxOwCCAHrM9oZz3M", "vapidPublic": "BK_EpP8NDm9waor2zn6_S28o3ZYv4kCkJOfYpO3pt3W6jnPmxrgTLANUBNbbyaNatPnSQ12De9CeqSYQrqWzHTs", "main": { - "apiKey": "testkey", - "applicationTitle": "Overseerr", - "applicationUrl": "", - "csrfProtection": false, - "cacheImages": false, - "defaultPermissions": 32, - "defaultQuotas": { - "movie": {}, - "tv": {} - }, - "hideAvailable": false, - "localLogin": true, - "newPlexLogin": true, - "region": "", - "originalLanguage": "", - "trustProxy": false, - "partialRequestsEnabled": true, - "locale": "en" + "apiKey": "testkey", + "applicationTitle": "Overseerr", + "applicationUrl": "", + "csrfProtection": false, + "cacheImages": false, + "defaultPermissions": 32, + "defaultQuotas": { + "movie": {}, + "tv": {} + }, + "hideAvailable": false, + "localLogin": true, + "newPlexLogin": true, + "region": "", + "originalLanguage": "", + "trustProxy": false, + "partialRequestsEnabled": true, + "locale": "en" }, "plex": { - "name": "Seerr", - "ip": "192.168.1.1", - "port": 32400, - "useSsl": false, - "libraries": [ - { - "id": "1", - "name": "Movies", - "enabled": true, - "type": "movie" - } - ], - "machineId": "test" + "name": "Seerr", + "ip": "192.168.1.1", + "port": 32400, + "useSsl": false, + "libraries": [ + { + "id": "1", + "name": "Movies", + "enabled": true, + "type": "movie" + } + ], + "machineId": "test" }, "tautulli": {}, "radarr": [], "sonarr": [], "public": { - "initialized": true + "initialized": true }, "notifications": { - "agents": { - "email": { - "enabled": false, - "options": { - "emailFrom": "", - "smtpHost": "", - "smtpPort": 587, - "secure": false, - "ignoreTls": false, - "requireTls": false, - "allowSelfSigned": false, - "senderName": "Overseerr" - } - }, - "discord": { - "enabled": false, - "types": 0, - "options": { - "webhookUrl": "", - "enableMentions": true - } - }, - "lunasea": { - "enabled": false, - "types": 0, - "options": { - "webhookUrl": "" - } - }, - "slack": { - "enabled": false, - "types": 0, - "options": { - "webhookUrl": "" - } - }, - "telegram": { - "enabled": false, - "types": 0, - "options": { - "botAPI": "", - "chatId": "", - "sendSilently": false - } + "agents": { + "email": { + "enabled": false, + "options": { + "emailFrom": "", + "smtpHost": "", + "smtpPort": 587, + "secure": false, + "ignoreTls": false, + "requireTls": false, + "allowSelfSigned": false, + "senderName": "Overseerr" + } + }, + "discord": { + "enabled": false, + "types": 0, + "options": { + "webhookUrl": "", + "enableMentions": true + } + }, + "lunasea": { + "enabled": false, + "types": 0, + "options": { + "webhookUrl": "" + } + }, + "slack": { + "enabled": false, + "types": 0, + "options": { + "webhookUrl": "" + } + }, + "telegram": { + "enabled": false, + "types": 0, + "options": { + "botAPI": "", + "chatId": "", + "sendSilently": false + } + }, + "pushbullet": { + "enabled": false, + "types": 0, + "options": { + "accessToken": "" + } + }, + "pushover": { + "enabled": false, + "types": 0, + "options": { + "accessToken": "", + "userToken": "" + } + }, + "webhook": { + "enabled": false, + "types": 0, + "options": { + "webhookUrl": "", + "jsonPayload": "IntcbiAgICBcIm5vdGlmaWNhdGlvbl90eXBlXCI6IFwie3tub3RpZmljYXRpb25fdHlwZX19XCIsXG4gICAgXCJldmVudFwiOiBcInt7ZXZlbnR9fVwiLFxuICAgIFwic3ViamVjdFwiOiBcInt7c3ViamVjdH19XCIsXG4gICAgXCJtZXNzYWdlXCI6IFwie3ttZXNzYWdlfX1cIixcbiAgICBcImltYWdlXCI6IFwie3tpbWFnZX19XCIsXG4gICAgXCJ7e21lZGlhfX1cIjoge1xuICAgICAgICBcIm1lZGlhX3R5cGVcIjogXCJ7e21lZGlhX3R5cGV9fVwiLFxuICAgICAgICBcInRtZGJJZFwiOiBcInt7bWVkaWFfdG1kYmlkfX1cIixcbiAgICAgICAgXCJ0dmRiSWRcIjogXCJ7e21lZGlhX3R2ZGJpZH19XCIsXG4gICAgICAgIFwic3RhdHVzXCI6IFwie3ttZWRpYV9zdGF0dXN9fVwiLFxuICAgICAgICBcInN0YXR1czRrXCI6IFwie3ttZWRpYV9zdGF0dXM0a319XCJcbiAgICB9LFxuICAgIFwie3tyZXF1ZXN0fX1cIjoge1xuICAgICAgICBcInJlcXVlc3RfaWRcIjogXCJ7e3JlcXVlc3RfaWR9fVwiLFxuICAgICAgICBcInJlcXVlc3RlZEJ5X2VtYWlsXCI6IFwie3tyZXF1ZXN0ZWRCeV9lbWFpbH19XCIsXG4gICAgICAgIFwicmVxdWVzdGVkQnlfdXNlcm5hbWVcIjogXCJ7e3JlcXVlc3RlZEJ5X3VzZXJuYW1lfX1cIixcbiAgICAgICAgXCJyZXF1ZXN0ZWRCeV9hdmF0YXJcIjogXCJ7e3JlcXVlc3RlZEJ5X2F2YXRhcn19XCJcbiAgICB9LFxuICAgIFwie3tpc3N1ZX19XCI6IHtcbiAgICAgICAgXCJpc3N1ZV9pZFwiOiBcInt7aXNzdWVfaWR9fVwiLFxuICAgICAgICBcImlzc3VlX3R5cGVcIjogXCJ7e2lzc3VlX3R5cGV9fVwiLFxuICAgICAgICBcImlzc3VlX3N0YXR1c1wiOiBcInt7aXNzdWVfc3RhdHVzfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X2VtYWlsXCI6IFwie3tyZXBvcnRlZEJ5X2VtYWlsfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X3VzZXJuYW1lXCI6IFwie3tyZXBvcnRlZEJ5X3VzZXJuYW1lfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X2F2YXRhclwiOiBcInt7cmVwb3J0ZWRCeV9hdmF0YXJ9fVwiXG4gICAgfSxcbiAgICBcInt7Y29tbWVudH19XCI6IHtcbiAgICAgICAgXCJjb21tZW50X21lc3NhZ2VcIjogXCJ7e2NvbW1lbnRfbWVzc2FnZX19XCIsXG4gICAgICAgIFwiY29tbWVudGVkQnlfZW1haWxcIjogXCJ7e2NvbW1lbnRlZEJ5X2VtYWlsfX1cIixcbiAgICAgICAgXCJjb21tZW50ZWRCeV91c2VybmFtZVwiOiBcInt7Y29tbWVudGVkQnlfdXNlcm5hbWV9fVwiLFxuICAgICAgICBcImNvbW1lbnRlZEJ5X2F2YXRhclwiOiBcInt7Y29tbWVudGVkQnlfYXZhdGFyfX1cIlxuICAgIH0sXG4gICAgXCJ7e2V4dHJhfX1cIjogW11cbn0i" + } + }, + "webpush": { + "enabled": false, + "options": {} + }, + "gotify": { + "enabled": false, + "types": 0, + "options": { + "url": "", + "token": "" + } + } + } + }, + "jobs": { + "plex-recently-added-scan": { + "schedule": "0 */5 * * * *" }, - "pushbullet": { - "enabled": false, - "types": 0, - "options": { - "accessToken": "" - } + "plex-full-scan": { + "schedule": "0 0 3 * * *" }, - "pushover": { - "enabled": false, - "types": 0, - "options": { - "accessToken": "", - "userToken": "" - } + "radarr-scan": { + "schedule": "0 0 4 * * *" }, - "webhook": { - "enabled": false, - "types": 0, - "options": { - "webhookUrl": "", - "jsonPayload": "IntcbiAgICBcIm5vdGlmaWNhdGlvbl90eXBlXCI6IFwie3tub3RpZmljYXRpb25fdHlwZX19XCIsXG4gICAgXCJldmVudFwiOiBcInt7ZXZlbnR9fVwiLFxuICAgIFwic3ViamVjdFwiOiBcInt7c3ViamVjdH19XCIsXG4gICAgXCJtZXNzYWdlXCI6IFwie3ttZXNzYWdlfX1cIixcbiAgICBcImltYWdlXCI6IFwie3tpbWFnZX19XCIsXG4gICAgXCJ7e21lZGlhfX1cIjoge1xuICAgICAgICBcIm1lZGlhX3R5cGVcIjogXCJ7e21lZGlhX3R5cGV9fVwiLFxuICAgICAgICBcInRtZGJJZFwiOiBcInt7bWVkaWFfdG1kYmlkfX1cIixcbiAgICAgICAgXCJ0dmRiSWRcIjogXCJ7e21lZGlhX3R2ZGJpZH19XCIsXG4gICAgICAgIFwic3RhdHVzXCI6IFwie3ttZWRpYV9zdGF0dXN9fVwiLFxuICAgICAgICBcInN0YXR1czRrXCI6IFwie3ttZWRpYV9zdGF0dXM0a319XCJcbiAgICB9LFxuICAgIFwie3tyZXF1ZXN0fX1cIjoge1xuICAgICAgICBcInJlcXVlc3RfaWRcIjogXCJ7e3JlcXVlc3RfaWR9fVwiLFxuICAgICAgICBcInJlcXVlc3RlZEJ5X2VtYWlsXCI6IFwie3tyZXF1ZXN0ZWRCeV9lbWFpbH19XCIsXG4gICAgICAgIFwicmVxdWVzdGVkQnlfdXNlcm5hbWVcIjogXCJ7e3JlcXVlc3RlZEJ5X3VzZXJuYW1lfX1cIixcbiAgICAgICAgXCJyZXF1ZXN0ZWRCeV9hdmF0YXJcIjogXCJ7e3JlcXVlc3RlZEJ5X2F2YXRhcn19XCJcbiAgICB9LFxuICAgIFwie3tpc3N1ZX19XCI6IHtcbiAgICAgICAgXCJpc3N1ZV9pZFwiOiBcInt7aXNzdWVfaWR9fVwiLFxuICAgICAgICBcImlzc3VlX3R5cGVcIjogXCJ7e2lzc3VlX3R5cGV9fVwiLFxuICAgICAgICBcImlzc3VlX3N0YXR1c1wiOiBcInt7aXNzdWVfc3RhdHVzfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X2VtYWlsXCI6IFwie3tyZXBvcnRlZEJ5X2VtYWlsfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X3VzZXJuYW1lXCI6IFwie3tyZXBvcnRlZEJ5X3VzZXJuYW1lfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X2F2YXRhclwiOiBcInt7cmVwb3J0ZWRCeV9hdmF0YXJ9fVwiXG4gICAgfSxcbiAgICBcInt7Y29tbWVudH19XCI6IHtcbiAgICAgICAgXCJjb21tZW50X21lc3NhZ2VcIjogXCJ7e2NvbW1lbnRfbWVzc2FnZX19XCIsXG4gICAgICAgIFwiY29tbWVudGVkQnlfZW1haWxcIjogXCJ7e2NvbW1lbnRlZEJ5X2VtYWlsfX1cIixcbiAgICAgICAgXCJjb21tZW50ZWRCeV91c2VybmFtZVwiOiBcInt7Y29tbWVudGVkQnlfdXNlcm5hbWV9fVwiLFxuICAgICAgICBcImNvbW1lbnRlZEJ5X2F2YXRhclwiOiBcInt7Y29tbWVudGVkQnlfYXZhdGFyfX1cIlxuICAgIH0sXG4gICAgXCJ7e2V4dHJhfX1cIjogW11cbn0i" - } + "sonarr-scan": { + "schedule": "0 30 4 * * *" }, - "webpush": { - "enabled": false, - "options": {} + "download-sync": { + "schedule": "0 * * * * *" }, - "gotify": { - "enabled": false, - "types": 0, - "options": { - "url": "", - "token": "" - } + "download-sync-reset": { + "schedule": "0 0 1 * * *" } - } - }, - "jobs": { - "plex-recently-added-scan": { - "schedule": "0 */5 * * * *" - }, - "plex-full-scan": { - "schedule": "0 0 3 * * *" - }, - "radarr-scan": { - "schedule": "0 0 4 * * *" - }, - "sonarr-scan": { - "schedule": "0 30 4 * * *" - }, - "download-sync": { - "schedule": "0 * * * * *" - }, - "download-sync-reset": { - "schedule": "0 0 1 * * *" - } } - } +} diff --git a/cypress/e2e/discover.cy.ts b/cypress/e2e/discover.cy.ts index 3489061b0e..545f25658b 100644 --- a/cypress/e2e/discover.cy.ts +++ b/cypress/e2e/discover.cy.ts @@ -36,7 +36,9 @@ describe('Discover', () => { }); it('loads upcoming movies', () => { - cy.intercept('/api/v1/discover/movies/upcoming*').as('getUpcomingMovies'); + cy.intercept('/api/v1/discover/movies?page=1&primaryReleaseDateGte*').as( + 'getUpcomingMovies' + ); cy.visit('/'); cy.wait('@getUpcomingMovies'); clickFirstTitleCardInSlider('Upcoming Movies'); @@ -50,7 +52,9 @@ describe('Discover', () => { }); it('loads upcoming series', () => { - cy.intercept('/api/v1/discover/tv/upcoming*').as('getUpcomingSeries'); + cy.intercept('/api/v1/discover/tv?page=1&firstAirDateGte=*').as( + 'getUpcomingSeries' + ); cy.visit('/'); cy.wait('@getUpcomingSeries'); clickFirstTitleCardInSlider('Upcoming Series'); diff --git a/cypress/e2e/pull-to-refresh.cy.ts b/cypress/e2e/pull-to-refresh.cy.ts index d56c55897a..732ee41377 100644 --- a/cypress/e2e/pull-to-refresh.cy.ts +++ b/cypress/e2e/pull-to-refresh.cy.ts @@ -13,7 +13,7 @@ describe('Pull To Refresh', () => { url: '/api/v1/*', }).as('apiCall'); - cy.get('.searchbar').swipe('bottom', [190, 400]); + cy.get('.searchbar').swipe('bottom', [190, 500]); cy.wait('@apiCall').then((interception) => { assert.isNotNull( diff --git a/cypress/e2e/settings/discover-customization.cy.ts b/cypress/e2e/settings/discover-customization.cy.ts new file mode 100644 index 0000000000..469994a3fb --- /dev/null +++ b/cypress/e2e/settings/discover-customization.cy.ts @@ -0,0 +1,163 @@ +describe('Discover Customization', () => { + beforeEach(() => { + cy.loginAsAdmin(); + cy.intercept('/api/v1/settings/discover').as('getDiscoverSliders'); + }); + + it('show the discover customization settings', () => { + cy.visit('/'); + + cy.get('[data-testid=discover-start-editing]').click(); + + cy.get('[data-testid=create-slider-header') + .should('contain', 'Create New Slider') + .scrollIntoView(); + + // There should be some built in options + cy.get('[data-testid=discover-slider-edit-mode]').should( + 'contain', + 'Recently Added' + ); + cy.get('[data-testid=discover-slider-edit-mode]').should( + 'contain', + 'Recent Requests' + ); + }); + + it('can drag to re-order elements and save to persist the changes', () => { + let dataTransfer = new DataTransfer(); + cy.visit('/'); + + cy.get('[data-testid=discover-start-editing]').click(); + + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .trigger('dragstart', { dataTransfer }); + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .trigger('drop', { dataTransfer }); + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .trigger('dragend', { dataTransfer }); + + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .should('contain', 'Recently Added'); + + cy.get('[data-testid=discover-customize-submit').click(); + cy.wait('@getDiscoverSliders'); + + cy.reload(); + + cy.get('[data-testid=discover-start-editing]').click(); + + dataTransfer = new DataTransfer(); + + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .should('contain', 'Recently Added'); + + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .trigger('dragstart', { dataTransfer }); + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .trigger('drop', { dataTransfer }); + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .trigger('dragend', { dataTransfer }); + + cy.get('[data-testid=discover-slider-edit-mode]') + .eq(1) + .should('contain', 'Recent Requests'); + + cy.get('[data-testid=discover-customize-submit').click(); + cy.wait('@getDiscoverSliders'); + }); + + it('can create a new discover option and remove it', () => { + cy.visit('/'); + cy.intercept('/api/v1/settings/discover/*').as('discoverSlider'); + cy.intercept('/api/v1/search/keyword*').as('searchKeyword'); + + cy.get('[data-testid=discover-start-editing]').click(); + + const sliderTitle = 'Custom Keyword Slider'; + + cy.get('#sliderType').select('TMDB Movie Keyword'); + + cy.get('#title').type(sliderTitle); + // First confirm that an invalid keyword doesn't allow us to submit anything + cy.get('#data').type('invalidkeyword{enter}', { delay: 100 }); + cy.wait('@searchKeyword'); + + cy.get('[data-testid=create-discover-option-form]') + .find('button') + .should('be.disabled'); + + cy.get('#data').clear(); + cy.get('#data').type('christmas{enter}', { delay: 100 }); + + // Confirming we have some results + cy.contains('.slider-header', sliderTitle) + .next('[data-testid=media-slider]') + .find('[data-testid=title-card]'); + + cy.get('[data-testid=create-discover-option-form]').submit(); + + cy.wait('@discoverSlider'); + cy.wait('@getDiscoverSliders'); + cy.wait(1000); + + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .should('contain', sliderTitle); + + // Make sure its still there even if we reload + cy.reload(); + + cy.get('[data-testid=discover-start-editing]').click(); + + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .should('contain', sliderTitle); + + // Verify it's not rendering on our discover page (its still disabled!) + cy.visit('/'); + + cy.get('.slider-header').should('not.contain', sliderTitle); + + cy.get('[data-testid=discover-start-editing]').click(); + + // Enable it, and check again + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .find('[role="checkbox"]') + .click(); + + cy.get('[data-testid=discover-customize-submit').click(); + cy.wait('@getDiscoverSliders'); + + cy.visit('/'); + + cy.contains('.slider-header', sliderTitle) + .next('[data-testid=media-slider]') + .find('[data-testid=title-card]'); + + cy.get('[data-testid=discover-start-editing]').click(); + + // let's delete it and confirm its deleted. + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .find('[data-testid=discover-slider-remove-button]') + .click(); + + cy.wait('@discoverSlider'); + cy.wait('@getDiscoverSliders'); + cy.wait(1000); + + cy.get('[data-testid=discover-slider-edit-mode]') + .first() + .should('not.contain', sliderTitle); + }); +}); diff --git a/cypress/e2e/settings/general-settings.cy.ts b/cypress/e2e/settings/general-settings.cy.ts index 3717f65b08..bcfce1a328 100644 --- a/cypress/e2e/settings/general-settings.cy.ts +++ b/cypress/e2e/settings/general-settings.cy.ts @@ -16,7 +16,7 @@ describe('General Settings', () => { cy.visit('/settings'); cy.get('#trustProxy').click(); - cy.get('form').submit(); + cy.get('[data-testid=settings-main-form]').submit(); cy.get('[data-testid=modal-title]').should( 'contain', 'Server Restart Required' @@ -26,7 +26,7 @@ describe('General Settings', () => { cy.get('[data-testid=modal-title]').should('not.exist'); cy.get('[type=checkbox]#trustProxy').click(); - cy.get('form').submit(); + cy.get('[data-testid=settings-main-form]').submit(); cy.get('[data-testid=modal-title]').should('not.exist'); }); }); diff --git a/docs/extending-overseerr/fail2ban.md b/docs/extending-overseerr/fail2ban.md index 1cf9131f0f..4f2b1c5941 100644 --- a/docs/extending-overseerr/fail2ban.md +++ b/docs/extending-overseerr/fail2ban.md @@ -11,4 +11,4 @@ To use Fail2ban with Overseerr, create a new file named `overseerr.local` in you failregex = .*\[warn\]\[API\]\: Failed sign-in attempt.*"ip":"" ``` -You can then add a jail using this filter in `jail.local`. Please see the [Fail2ban documetation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails) for details on how to configure the jail. +You can then add a jail using this filter in `jail.local`. Please see the [Fail2ban documentation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails) for details on how to configure the jail. diff --git a/docs/extending-overseerr/reverse-proxy.md b/docs/extending-overseerr/reverse-proxy.md index 84752f7c2c..ec456fdbc1 100644 --- a/docs/extending-overseerr/reverse-proxy.md +++ b/docs/extending-overseerr/reverse-proxy.md @@ -141,7 +141,7 @@ location ^~ /overseerr { sub_filter '\/_next' '\/$app\/_next'; sub_filter '/_next' '/$app/_next'; sub_filter '/api/v1' '/$app/api/v1'; - sub_filter '/login/plex/loading' '/$app/login/plex/loading'; + sub_filter '/login/popup/loading' '/$app/login/popup/loading'; sub_filter '/images/' '/$app/images/'; sub_filter '/android-' '/$app/android-'; sub_filter '/apple-' '/$app/apple-'; diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 98e26f59f7..abaef46aae 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -28,6 +28,7 @@ docker run -d \ --name overseerr \ -e LOG_LEVEL=debug \ -e TZ=Asia/Tokyo \ + -e PORT=5055 `#optional` \ -p 5055:5055 \ -v /path/to/appdata/config:/app/config \ --restart unless-stopped \ @@ -81,6 +82,7 @@ services: environment: - LOG_LEVEL=debug - TZ=Asia/Tokyo + - PORT=5055 #optional ports: - 5055:5055 volumes: @@ -88,7 +90,7 @@ services: restart: unless-stopped ``` -Then, start all services defined in the your Compose file: +Then, start all services defined in the Compose file: ```bash docker-compose up -d @@ -146,8 +148,6 @@ Then, create and start the Overseerr container: docker run -d --name overseerr -e LOG_LEVEL=debug -e TZ=Asia/Tokyo -p 5055:5055 -v "overseerr-data:/app/config" --restart unless-stopped sctx/overseerr:latest ``` -If using a named volume like above, you can safely ignore the warning about the `/app/config` folder being incorrectly mounted on the setup page. - To access the files inside the volume created above, navigate to `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\overseerr-data\_data` using File Explorer. {% hint style="info" %} @@ -155,7 +155,7 @@ Docker on Windows works differently than it does on Linux; it runs Docker inside **If you must run Docker on Windows, you should put the `/app/config` directory mount inside the VM and not on the Windows host.** (This also applies to other containers with SQLite databases.) -Named volumes, like in the example commands above, are automatically mounted inside the VM. +Named volumes, like in the example commands above, are automatically mounted inside the VM. Therefore the warning on the setup about the `/app/config` folder being incorrectly mounted page should be ignored. {% endhint %} ## Linux diff --git a/docs/using-overseerr/settings/README.md b/docs/using-overseerr/settings/README.md index 820430736e..477129fc91 100644 --- a/docs/using-overseerr/settings/README.md +++ b/docs/using-overseerr/settings/README.md @@ -40,6 +40,14 @@ If you enable this setting and find yourself unable to access Overseerr, you can This setting is **disabled** by default. +### Enable Image Caching + +When enabled, Overseerr will proxy and cache images from pre-configured sources (such as TMDB). This can use a significant amount of disk space. + +Images are saved in the `config/cache/images` and stale images are cleared out every 24 hours. + +You should enable this if you are having issues with loading images directly from TMDB in your browser. + ### Display Language Set the default display language for Overseerr. Users can override this setting in their user settings. diff --git a/next.config.js b/next.config.js index b0e872e885..9cd65f9734 100644 --- a/next.config.js +++ b/next.config.js @@ -19,5 +19,6 @@ module.exports = { }, experimental: { scrollRestoration: true, + largePageDataBytes: 256000, }, }; diff --git a/overseerr-api.yml b/overseerr-api.yml index 164187de3d..ea800b708f 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -26,6 +26,8 @@ tags: description: Endpoints related to retrieving movies and their details. - name: tv description: Endpoints related to retrieving TV series and their details. + - name: other + description: Endpoints related to other TMDB data - name: person description: Endpoints related to retrieving person details. - name: media @@ -600,6 +602,17 @@ components: name: type: string example: Adventure + Company: + type: object + properties: + id: + type: number + example: 1 + logo_path: + type: string + nullable: true + name: + type: string ProductionCompany: type: object properties: @@ -1039,6 +1052,8 @@ components: nullable: true status: type: number + example: 0 + description: Availability of the media. 1 = `UNKNOWN`, 2 = `PENDING`, 3 = `PROCESSING`, 4 = `PARTIALLY_AVAILABLE`, 5 = `AVAILABLE` requests: type: array readOnly: true @@ -1258,6 +1273,8 @@ components: type: string userToken: type: string + sound: + type: string GotifySettings: type: object properties: @@ -1693,6 +1710,9 @@ components: pushoverUserKey: type: string nullable: true + pushoverSound: + type: string + nullable: true telegramEnabled: type: boolean telegramBotUsername: @@ -1780,6 +1800,40 @@ components: message: type: string example: A comment + DiscoverSlider: + type: object + properties: + id: + type: number + example: 1 + type: + type: number + example: 1 + title: + type: string + nullable: true + isBuiltIn: + type: boolean + enabled: + type: boolean + data: + type: string + example: '1234' + nullable: true + required: + - type + - enabled + - title + - data + WatchProviderRegion: + type: object + properties: + iso_3166_1: + type: string + english_name: + type: string + native_name: + type: string securitySchemes: cookieAuth: type: apiKey @@ -2475,29 +2529,44 @@ paths: content: application/json: schema: - type: array - items: - type: object - properties: - id: - type: string - example: cache-id - name: - type: string - example: cache name - stats: + type: object + properties: + imageCache: + type: object + properties: + tmdb: + type: object + properties: + size: + type: number + example: 123456 + imageCount: + type: number + example: 123 + apiCaches: + type: array + items: type: object properties: - hits: - type: number - misses: - type: number - keys: - type: number - ksize: - type: number - vsize: - type: number + id: + type: string + example: cache-id + name: + type: string + example: cache name + stats: + type: object + properties: + hits: + type: number + misses: + type: number + keys: + type: number + ksize: + type: number + vsize: + type: number /settings/cache/{cacheId}/flush: post: summary: Flush a specific cache @@ -2797,6 +2866,33 @@ paths: responses: '204': description: Test notification attempted + /settings/notifications/pushover/sounds: + get: + summary: Get Pushover sounds + description: Returns valid Pushover sound options in a JSON array. + tags: + - settings + parameters: + - in: query + name: token + required: true + schema: + type: string + nullable: false + responses: + '200': + description: Returned Pushover settings + content: + application/json: + schema: + type: array + items: + type: object + properties: + name: + type: string + description: + type: string /settings/notifications/gotify: get: summary: Get Gotify notification settings @@ -3027,6 +3123,133 @@ paths: responses: '204': description: Test notification attempted + /settings/discover: + get: + summary: Get all discover sliders + description: Returns all discovery sliders. Built-in and custom made. + tags: + - settings + responses: + '200': + description: Returned all discovery sliders + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/DiscoverSlider' + post: + summary: Batch update all sliders. + description: | + Batch update all sliders at once. Should also be used for creation. Will only update sliders provided + and will not delete any sliders not present in the request. If a slider is missing a required field, + it will be ignored. Requires the `ADMIN` permission. + tags: + - settings + requestBody: + required: true + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/DiscoverSlider' + responses: + '200': + description: Returned all newly updated discovery sliders + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/DiscoverSlider' + /settings/discover/{sliderId}: + put: + summary: Update a single slider + description: | + Updates a single slider and return the newly updated slider. Requires the `ADMIN` permission. + tags: + - settings + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + title: + type: string + example: 'Slider Title' + type: + type: number + example: 1 + data: + type: string + example: '1' + responses: + '200': + description: Returns newly added discovery slider + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoverSlider' + delete: + summary: Delete slider by ID + description: Deletes the slider with the provided sliderId. Requires the `ADMIN` permission. + tags: + - settings + parameters: + - in: path + name: sliderId + required: true + schema: + type: number + responses: + '200': + description: Slider successfully deleted + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoverSlider' + /settings/discover/add: + post: + summary: Add a new slider + description: | + Add a single slider and return the newly created slider. Requires the `ADMIN` permission. + tags: + - settings + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + title: + type: string + example: 'New Slider' + type: + type: number + example: 1 + data: + type: string + example: '1' + responses: + '200': + description: Returns newly added discovery slider + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoverSlider' + /settings/discover/reset: + get: + summary: Reset all discover sliders + description: Resets all discovery sliders to the default values. Requires the `ADMIN` permission. + tags: + - settings + responses: + '204': + description: All sliders reset to defaults /settings/about: get: summary: Get server stats @@ -3206,6 +3429,80 @@ paths: type: string required: - password + /auth/oidc-login: + get: + security: [] + summary: Redirect to the OpenID Connect provider + description: Constructs the redirect URL to the OpenID Connect provider, and redirects the user to it. + tags: + - auth + responses: + '302': + description: Redirect to the authentication url for the OpenID Connect provider + headers: + Location: + schema: + type: string + example: https://example.com/auth/oidc/callback?response_type=code&client_id=client_id&redirect_uri=https%3A%2F%2Fexample.com%2Fauth%2Foidc%2Fcallback&scope=openid%20email&state=state + Set-Cookie: + schema: + type: string + example: 'oidc-state=123456789; HttpOnly; max-age=60000; Secure' + /auth/oidc-callback: + get: + security: [] + summary: The callback endpoint for the OpenID Connect provider redirect + description: Takes the `code` and `state` parameters from the OpenID Connect provider, and exchanges them for a token. + parameters: + - in: query + name: code + required: true + schema: + type: string + example: '123456789' + - in: query + name: state + required: true + schema: + type: string + example: '123456789' + - in: query + name: scope + required: false + allowReserved: true + schema: + type: string + example: 'openid email profile' + - in: query + name: error + required: false + schema: + type: string + - in: query + name: error_description + required: false + schema: + type: string + - in: cookie + name: oidc-state + required: true + schema: + type: string + example: '123456789' + tags: + - auth + responses: + '302': + description: A redirect to the home page if successful or back to the login page if not + headers: + Location: + schema: + type: string + example: / + Set-Cookie: + schema: + type: string + example: 'oidc-state=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' /user: get: summary: Get all users @@ -3424,7 +3721,7 @@ paths: $ref: '#/components/schemas/User' /user/{userId}/requests: get: - summary: Get user by ID + summary: Get requests for a specific user description: | Retrieves a user's requests in a JSON object. tags: @@ -3520,7 +3817,7 @@ paths: example: false /user/{userId}/watchlist: get: - summary: Get user by ID + summary: Get the Plex watchlist for a specific user description: | Retrieves a user's Plex Watchlist in a JSON object. tags: @@ -3847,6 +4144,86 @@ paths: - $ref: '#/components/schemas/MovieResult' - $ref: '#/components/schemas/TvResult' - $ref: '#/components/schemas/PersonResult' + /search/keyword: + get: + summary: Search for keywords + description: Returns a list of TMDB keywords matching the search query + tags: + - search + parameters: + - in: query + name: query + required: true + schema: + type: string + example: 'christmas' + - in: query + name: page + schema: + type: number + example: 1 + default: 1 + responses: + '200': + description: Results + content: + application/json: + schema: + type: object + properties: + page: + type: number + example: 1 + totalPages: + type: number + example: 20 + totalResults: + type: number + example: 200 + results: + type: array + items: + $ref: '#/components/schemas/Keyword' + /search/company: + get: + summary: Search for companies + description: Returns a list of TMDB companies matching the search query. (Will not return origin country) + tags: + - search + parameters: + - in: query + name: query + required: true + schema: + type: string + example: 'Disney' + - in: query + name: page + schema: + type: number + example: 1 + default: 1 + responses: + '200': + description: Results + content: + application/json: + schema: + type: object + properties: + page: + type: number + example: 1 + totalPages: + type: number + example: 20 + totalResults: + type: number + example: 200 + results: + type: array + items: + $ref: '#/components/schemas/Company' /discover/movies: get: summary: Discover movies @@ -3868,13 +4245,73 @@ paths: - in: query name: genre schema: - type: number + type: string example: 18 - in: query name: studio schema: type: number example: 1 + - in: query + name: keywords + schema: + type: string + example: 1,2 + - in: query + name: sortBy + schema: + type: string + example: popularity.desc + - in: query + name: primaryReleaseDateGte + schema: + type: string + example: 2022-01-01 + - in: query + name: primaryReleaseDateLte + schema: + type: string + example: 2023-01-01 + - in: query + name: withRuntimeGte + schema: + type: number + example: 60 + - in: query + name: withRuntimeLte + schema: + type: number + example: 120 + - in: query + name: voteAverageGte + schema: + type: number + example: 7 + - in: query + name: voteAverageLte + schema: + type: number + example: 10 + - in: query + name: voteCountGte + schema: + type: number + example: 7 + - in: query + name: voteCountLte + schema: + type: number + example: 10 + - in: query + name: watchRegion + schema: + type: string + example: US + - in: query + name: watchProviders + schema: + type: string + example: 8|9 responses: '200': description: Results @@ -4097,13 +4534,73 @@ paths: - in: query name: genre schema: - type: number + type: string example: 18 - in: query name: network schema: type: number example: 1 + - in: query + name: keywords + schema: + type: string + example: 1,2 + - in: query + name: sortBy + schema: + type: string + example: popularity.desc + - in: query + name: firstAirDateGte + schema: + type: string + example: 2022-01-01 + - in: query + name: firstAirDateLte + schema: + type: string + example: 2023-01-01 + - in: query + name: withRuntimeGte + schema: + type: number + example: 60 + - in: query + name: withRuntimeLte + schema: + type: number + example: 120 + - in: query + name: voteAverageGte + schema: + type: number + example: 7 + - in: query + name: voteAverageLte + schema: + type: number + example: 10 + - in: query + name: voteCountGte + schema: + type: number + example: 7 + - in: query + name: voteCountLte + schema: + type: number + example: 10 + - in: query + name: watchRegion + schema: + type: string + example: US + - in: query + name: watchProviders + schema: + type: string + example: 8|9 responses: '200': description: Results @@ -4585,9 +5082,13 @@ paths: type: number example: 123 seasons: - type: array - items: - type: number + oneOf: + - type: array + items: + type: number + minimum: 1 + - type: string + enum: [all] is4k: type: boolean example: false @@ -4666,7 +5167,7 @@ paths: $ref: '#/components/schemas/MediaRequest' put: summary: Update MediaRequest - description: Updates a specific media request and returns the request in a JSON object.. Requires the `MANAGE_REQUESTS` permission. + description: Updates a specific media request and returns the request in a JSON object. Requires the `MANAGE_REQUESTS` permission. tags: - request parameters: @@ -4677,6 +5178,37 @@ paths: example: '1' schema: type: string + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + mediaType: + type: string + enum: [movie, tv] + seasons: + type: array + items: + type: number + minimum: 1 + is4k: + type: boolean + example: false + serverId: + type: number + profileId: + type: number + rootFolder: + type: string + languageProfileId: + type: number + userId: + type: number + nullable: true + required: + - mediaType responses: '200': description: Succesfully updated request @@ -4747,7 +5279,7 @@ paths: required: true schema: type: string - enum: [pending, approve, decline, available] + enum: [approve, decline] responses: '200': description: Request status changed @@ -4912,6 +5444,63 @@ paths: audienceRating: type: string enum: ['Spilled', 'Upright'] + /movie/{movieId}/ratingscombined: + get: + summary: Get RT and IMDB movie ratings combined + description: Returns ratings from RottenTomatoes and IMDB based on the provided movieId in a JSON object. + tags: + - movies + parameters: + - in: path + name: movieId + required: true + schema: + type: number + example: 337401 + responses: + '200': + description: Ratings returned + content: + application/json: + schema: + type: object + properties: + rt: + type: object + properties: + title: + type: string + example: Mulan + year: + type: number + example: 2020 + url: + type: string + example: 'http://www.rottentomatoes.com/m/mulan_2020/' + criticsScore: + type: number + example: 85 + criticsRating: + type: string + enum: ['Rotten', 'Fresh', 'Certified Fresh'] + audienceScore: + type: number + example: 65 + audienceRating: + type: string + enum: ['Spilled', 'Upright'] + imdb: + type: object + properties: + title: + type: string + example: I am Legend + url: + type: string + example: 'https://www.imdb.com/title/tt0480249' + criticsScore: + type: number + example: 6.5 /tv/{tvId}: get: summary: Get TV details @@ -5867,6 +6456,89 @@ paths: application/json: schema: $ref: '#/components/schemas/Issue' + /keyword/{keywordId}: + get: + summary: Get keyword + description: | + Returns a single keyword in JSON format. + tags: + - other + parameters: + - in: path + name: keywordId + required: true + schema: + type: number + example: 1 + responses: + '200': + description: Keyword returned + content: + application/json: + schema: + $ref: '#/components/schemas/Keyword' + /watchproviders/regions: + get: + summary: Get watch provider regions + description: | + Returns a list of all available watch provider regions. + tags: + - other + responses: + '200': + description: Watch provider regions returned + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WatchProviderRegion' + /watchproviders/movies: + get: + summary: Get watch provider movies + description: | + Returns a list of all available watch providers for movies. + tags: + - other + parameters: + - in: query + name: watchRegion + required: true + schema: + type: string + example: US + responses: + '200': + description: Watch providers for movies returned + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WatchProviderDetails' + /watchproviders/tv: + get: + summary: Get watch provider series + description: | + Returns a list of all available watch providers for series. + tags: + - other + parameters: + - in: query + name: watchRegion + required: true + schema: + type: string + example: US + responses: + '200': + description: Watch providers for series returned + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WatchProviderDetails' security: - cookieAuth: [] - apiKey: [] diff --git a/package.json b/package.json index 3a1d60de64..92aae6dc3b 100644 --- a/package.json +++ b/package.json @@ -29,144 +29,148 @@ }, "license": "MIT", "dependencies": { - "@formatjs/intl-displaynames": "6.0.3", - "@formatjs/intl-locale": "3.0.3", - "@formatjs/intl-pluralrules": "5.0.3", + "@formatjs/intl-displaynames": "6.2.6", + "@formatjs/intl-locale": "3.1.1", + "@formatjs/intl-pluralrules": "5.1.10", "@formatjs/intl-utils": "3.8.4", - "@headlessui/react": "0.0.0-insiders.b301f04", - "@heroicons/react": "1.0.6", + "@headlessui/react": "1.7.12", + "@heroicons/react": "2.0.16", "@supercharge/request-ip": "1.2.0", - "@svgr/webpack": "6.3.1", - "@tanem/react-nprogress": "5.0.11", - "ace-builds": "1.9.6", - "axios": "0.27.2", + "@svgr/webpack": "6.5.1", + "@tanem/react-nprogress": "5.0.30", + "ace-builds": "1.15.2", + "axios": "1.3.4", "axios-rate-limit": "1.3.0", - "bcrypt": "5.0.1", + "bcrypt": "5.1.0", "bowser": "2.11.0", "connect-typeorm": "1.1.4", "cookie-parser": "1.4.6", - "copy-to-clipboard": "3.3.2", + "copy-to-clipboard": "3.3.3", "country-flag-icons": "1.5.5", - "cronstrue": "2.11.0", + "cronstrue": "2.23.0", "csurf": "1.11.0", - "date-fns": "2.29.1", + "date-fns": "2.29.3", + "dayjs": "1.11.7", "email-templates": "9.0.0", - "express": "4.18.1", + "express": "4.18.2", "express-openapi-validator": "4.13.8", - "express-rate-limit": "6.5.1", + "express-rate-limit": "6.7.0", "express-session": "1.17.3", "formik": "2.2.9", "gravatar-url": "3.1.0", "intl": "1.2.5", + "jwt-decode": "^3.1.2", "lodash": "4.17.21", - "next": "12.2.5", + "next": "12.3.4", "node-cache": "5.1.2", - "node-gyp": "9.1.0", - "node-schedule": "2.1.0", - "nodemailer": "6.7.8", - "openpgp": "5.4.0", + "node-gyp": "9.3.1", + "node-schedule": "2.1.1", + "nodemailer": "6.9.1", + "openpgp": "5.7.0", "plex-api": "5.3.2", "pug": "3.0.2", - "pulltorefreshjs": "0.1.22", "react": "18.2.0", "react-ace": "10.1.0", "react-animate-height": "2.1.2", + "react-aria": "3.23.0", "react-dom": "18.2.0", - "react-intersection-observer": "9.4.0", - "react-intl": "6.0.5", - "react-markdown": "8.0.3", + "react-intersection-observer": "9.4.3", + "react-intl": "6.2.10", + "react-markdown": "8.0.5", "react-popper-tooltip": "4.4.2", - "react-select": "5.4.0", - "react-spring": "9.5.2", + "react-select": "5.7.0", + "react-spring": "9.7.1", + "react-tailwindcss-datepicker-sct": "1.3.4", "react-toast-notifications": "2.5.1", "react-truncate-markup": "5.1.2", - "react-use-clipboard": "1.0.8", + "react-use-clipboard": "1.0.9", "reflect-metadata": "0.1.13", "secure-random-password": "0.2.3", - "semver": "7.3.7", - "sqlite3": "5.0.11", - "swagger-ui-express": "4.5.0", - "swr": "1.3.0", - "typeorm": "0.3.7", + "semver": "7.3.8", + "sqlite3": "5.1.4", + "swagger-ui-express": "4.6.2", + "swr": "2.0.4", + "typeorm": "0.3.12", "web-push": "3.5.0", - "winston": "3.8.1", + "winston": "3.8.2", "winston-daily-rotate-file": "4.7.1", "xml2js": "0.4.23", "yamljs": "0.3.0", - "yup": "0.32.11" + "yup": "0.32.11", + "zod": "3.20.6" }, "devDependencies": { - "@babel/cli": "7.18.10", - "@commitlint/cli": "17.0.3", - "@commitlint/config-conventional": "17.0.3", - "@semantic-release/changelog": "6.0.1", + "@babel/cli": "7.21.0", + "@commitlint/cli": "17.4.4", + "@commitlint/config-conventional": "17.4.4", + "@semantic-release/changelog": "6.0.2", "@semantic-release/commit-analyzer": "9.0.2", "@semantic-release/exec": "6.0.3", "@semantic-release/git": "10.0.1", - "@tailwindcss/aspect-ratio": "0.4.0", - "@tailwindcss/forms": "0.5.2", - "@tailwindcss/typography": "0.5.4", + "@tailwindcss/aspect-ratio": "0.4.2", + "@tailwindcss/forms": "0.5.3", + "@tailwindcss/typography": "0.5.9", "@types/bcrypt": "5.0.0", "@types/cookie-parser": "1.4.3", "@types/country-flag-icons": "1.2.0", "@types/csurf": "1.11.2", "@types/email-templates": "8.0.4", - "@types/express": "4.17.13", - "@types/express-session": "1.17.4", - "@types/lodash": "4.14.183", + "@types/express": "4.17.17", + "@types/express-session": "1.17.6", + "@types/lodash": "4.14.191", "@types/node": "17.0.36", "@types/node-schedule": "2.1.0", - "@types/nodemailer": "6.4.5", - "@types/pulltorefreshjs": "0.1.5", - "@types/react": "18.0.17", - "@types/react-dom": "18.0.6", + "@types/nodemailer": "6.4.7", + "@types/react": "18.0.28", + "@types/react-dom": "18.0.11", "@types/react-transition-group": "4.4.5", "@types/secure-random-password": "0.2.1", - "@types/semver": "7.3.12", + "@types/semver": "7.3.13", "@types/swagger-ui-express": "4.1.3", "@types/web-push": "3.3.2", "@types/xml2js": "0.4.11", "@types/yamljs": "0.2.31", "@types/yup": "0.29.14", - "@typescript-eslint/eslint-plugin": "5.33.1", - "@typescript-eslint/parser": "5.33.1", - "autoprefixer": "10.4.8", + "@typescript-eslint/eslint-plugin": "5.54.0", + "@typescript-eslint/parser": "5.54.0", + "autoprefixer": "10.4.13", "babel-plugin-react-intl": "8.2.25", "babel-plugin-react-intl-auto": "3.3.0", - "commitizen": "4.2.5", + "commitizen": "4.3.0", "copyfiles": "2.4.1", "cy-mobile-commands": "0.3.0", - "cypress": "10.6.0", + "cypress": "12.7.0", "cz-conventional-changelog": "3.3.0", - "eslint": "8.22.0", - "eslint-config-next": "12.2.5", - "eslint-config-prettier": "8.5.0", - "eslint-plugin-formatjs": "4.1.0", - "eslint-plugin-jsx-a11y": "6.6.1", - "eslint-plugin-no-relative-import-paths": "1.4.0", + "eslint": "8.35.0", + "eslint-config-next": "12.3.4", + "eslint-config-prettier": "8.6.0", + "eslint-plugin-formatjs": "4.9.0", + "eslint-plugin-jsx-a11y": "6.7.1", + "eslint-plugin-no-relative-import-paths": "1.5.2", "eslint-plugin-prettier": "4.2.1", - "eslint-plugin-react": "7.30.1", + "eslint-plugin-react": "7.32.2", "eslint-plugin-react-hooks": "4.6.0", "extract-react-intl-messages": "4.1.1", - "husky": "8.0.1", - "lint-staged": "12.4.3", - "nodemon": "2.0.19", - "postcss": "8.4.16", - "prettier": "2.7.1", - "prettier-plugin-organize-imports": "3.1.0", - "prettier-plugin-tailwindcss": "0.1.13", - "semantic-release": "19.0.3", + "husky": "8.0.3", + "lint-staged": "13.1.2", + "nodemon": "2.0.20", + "postcss": "8.4.21", + "prettier": "2.8.4", + "prettier-plugin-organize-imports": "3.2.2", + "prettier-plugin-tailwindcss": "0.2.3", + "semantic-release": "19.0.5", "semantic-release-docker-buildx": "1.0.1", - "tailwindcss": "3.1.8", + "tailwindcss": "3.2.7", "ts-node": "10.9.1", - "tsc-alias": "1.7.0", - "tsconfig-paths": "4.1.0", - "typescript": "4.7.4" + "tsc-alias": "1.8.2", + "tsconfig-paths": "4.1.2", + "typescript": "4.9.5" }, "resolutions": { "sqlite3/node-gyp": "8.4.1", - "@types/react": "18.0.17", - "@types/react-dom": "18.0.6" + "@types/react": "18.0.28", + "@types/react-dom": "18.0.11", + "@types/express-session": "1.17.6" }, "config": { "commitizen": { @@ -224,7 +228,7 @@ { "path": "semantic-release-docker-buildx", "buildArgs": { - "COMMIT_TAG": "$GITHUB_SHA" + "COMMIT_TAG": "$GIT_SHA" }, "imageNames": [ "sctx/overseerr", diff --git a/public/offline.html b/public/offline.html index 732782ee11..da4ba235a4 100644 --- a/public/offline.html +++ b/public/offline.html @@ -17,7 +17,7 @@ } h1 { - color: #6366F1; + color: #6366f1; } p { @@ -37,7 +37,7 @@

You are offline