Compare commits
1 Commits
preview-fi
...
preview-fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6dc00c8732 |
@@ -18,7 +18,7 @@ config/logs/*
|
|||||||
config/*.json
|
config/*.json
|
||||||
dist
|
dist
|
||||||
Dockerfile*
|
Dockerfile*
|
||||||
compose.yaml
|
docker-compose.yml
|
||||||
docs
|
docs
|
||||||
LICENSE
|
LICENSE
|
||||||
node_modules
|
node_modules
|
||||||
|
|||||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -40,7 +40,7 @@ docs export-ignore
|
|||||||
.all-contributorsrc export-ignore
|
.all-contributorsrc export-ignore
|
||||||
.editorconfig export-ignore
|
.editorconfig export-ignore
|
||||||
Dockerfile.local export-ignore
|
Dockerfile.local export-ignore
|
||||||
compose.yaml export-ignore
|
docker-compose.yml export-ignore
|
||||||
stylelint.config.js export-ignore
|
stylelint.config.js export-ignore
|
||||||
|
|
||||||
public/os_logo_filled.png export-ignore
|
public/os_logo_filled.png export-ignore
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ All help is welcome and greatly appreciated! If you would like to contribute to
|
|||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
|
||||||
- Alternatively, you can use [Docker](https://www.docker.com/) with `docker compose up -d`. This method does not require installing NodeJS or Yarn on your machine directly.
|
- Alternatively, you can use [Docker](https://www.docker.com/) with `docker-compose up -d`. This method does not require installing NodeJS or Yarn on your machine directly.
|
||||||
|
|
||||||
5. Create your patch and test your changes.
|
5. Create your patch and test your changes.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
version: '3'
|
||||||
services:
|
services:
|
||||||
jellyseerr:
|
jellyseerr:
|
||||||
build:
|
build:
|
||||||
@@ -190,7 +190,7 @@ Caddy will automatically obtain and renew SSL certificates for your domain.
|
|||||||
|
|
||||||
## Traefik (v2)
|
## Traefik (v2)
|
||||||
|
|
||||||
Add the following labels to the Jellyseerr service in your `compose.yaml` file:
|
Add the following labels to the Jellyseerr service in your `docker-compose.yml` file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ You could also use [diun](https://github.com/crazy-max/diun) to receive notifica
|
|||||||
For details on how to use Docker Compose, please [review the official Compose documentation](https://docs.docker.com/compose/reference/).
|
For details on how to use Docker Compose, please [review the official Compose documentation](https://docs.docker.com/compose/reference/).
|
||||||
|
|
||||||
#### Installation:
|
#### Installation:
|
||||||
Define the `jellyseerr` service in your `compose.yaml` as follows:
|
Define the `jellyseerr` service in your `docker-compose.yml` as follows:
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
services:
|
services:
|
||||||
@@ -94,17 +94,17 @@ If you are using emby, make sure to set the `JELLYFIN_TYPE` environment variable
|
|||||||
|
|
||||||
Then, start all services defined in the Compose file:
|
Then, start all services defined in the Compose file:
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Updating:
|
#### Updating:
|
||||||
Pull the latest image:
|
Pull the latest image:
|
||||||
```bash
|
```bash
|
||||||
docker compose pull jellyseerr
|
docker-compose pull jellyseerr
|
||||||
```
|
```
|
||||||
Then, restart all services defined in the Compose file:
|
Then, restart all services defined in the Compose file:
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
:::tip
|
:::tip
|
||||||
You may alternatively use a third-party mechanism like [dockge](https://github.com/louislam/dockge) to manage your docker compose files.
|
You may alternatively use a third-party mechanism like [dockge](https://github.com/louislam/dockge) to manage your docker compose files.
|
||||||
|
|||||||
@@ -299,84 +299,54 @@ authRoutes.post('/jellyfin', async (req, res, next) => {
|
|||||||
where: { jellyfinUserId: account.User.Id },
|
where: { jellyfinUserId: account.User.Id },
|
||||||
});
|
});
|
||||||
|
|
||||||
const missingAdminUser = !user && !(await userRepository.count());
|
if (!user && !(await userRepository.count())) {
|
||||||
if (
|
|
||||||
missingAdminUser ||
|
|
||||||
settings.main.mediaServerType === MediaServerType.NOT_CONFIGURED
|
|
||||||
) {
|
|
||||||
// Check if user is admin on jellyfin
|
// Check if user is admin on jellyfin
|
||||||
if (account.User.Policy.IsAdministrator === false) {
|
if (account.User.Policy.IsAdministrator === false) {
|
||||||
throw new ApiError(403, ApiErrorCode.NotAdmin);
|
throw new ApiError(403, ApiErrorCode.NotAdmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
logger.info(
|
||||||
body.serverType !== MediaServerType.JELLYFIN &&
|
'Sign-in attempt from Jellyfin user with access to the media server; creating initial admin user for Overseerr',
|
||||||
body.serverType !== MediaServerType.EMBY
|
{
|
||||||
) {
|
label: 'API',
|
||||||
throw new Error('select_server_type');
|
ip: req.ip,
|
||||||
}
|
|
||||||
settings.main.mediaServerType = body.serverType;
|
|
||||||
|
|
||||||
if (missingAdminUser) {
|
|
||||||
logger.info(
|
|
||||||
'Sign-in attempt from Jellyfin user with access to the media server; creating initial admin user for Jellyseerr',
|
|
||||||
{
|
|
||||||
label: 'API',
|
|
||||||
ip: req.ip,
|
|
||||||
jellyfinUsername: account.User.Name,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// User doesn't exist, and there are no users in the database, we'll create the user
|
|
||||||
// with admin permissions
|
|
||||||
|
|
||||||
user = new User({
|
|
||||||
id: 1,
|
|
||||||
email: body.email || account.User.Name,
|
|
||||||
jellyfinUsername: account.User.Name,
|
jellyfinUsername: account.User.Name,
|
||||||
jellyfinUserId: account.User.Id,
|
|
||||||
jellyfinDeviceId: deviceId,
|
|
||||||
jellyfinAuthToken: account.AccessToken,
|
|
||||||
permissions: Permission.ADMIN,
|
|
||||||
avatar: `/avatarproxy/${account.User.Id}`,
|
|
||||||
userType:
|
|
||||||
body.serverType === MediaServerType.JELLYFIN
|
|
||||||
? UserType.JELLYFIN
|
|
||||||
: UserType.EMBY,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userRepository.save(user);
|
|
||||||
} else {
|
|
||||||
logger.info(
|
|
||||||
'Sign-in attempt from Jellyfin user with access to the media server; editing admin user for Jellyseerr',
|
|
||||||
{
|
|
||||||
label: 'API',
|
|
||||||
ip: req.ip,
|
|
||||||
jellyfinUsername: account.User.Name,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// User alread exist but settings.json is not configured, we'll edit the admin user
|
|
||||||
|
|
||||||
user = await userRepository.findOne({
|
|
||||||
where: { id: 1 },
|
|
||||||
});
|
|
||||||
if (!user) {
|
|
||||||
throw new Error('Unable to find admin user to edit');
|
|
||||||
}
|
}
|
||||||
user.email = body.email || account.User.Name;
|
);
|
||||||
user.jellyfinUsername = account.User.Name;
|
|
||||||
user.jellyfinUserId = account.User.Id;
|
|
||||||
user.jellyfinDeviceId = deviceId;
|
|
||||||
user.jellyfinAuthToken = account.AccessToken;
|
|
||||||
user.permissions = Permission.ADMIN;
|
|
||||||
user.avatar = `/avatarproxy/${account.User.Id}`;
|
|
||||||
user.userType =
|
|
||||||
body.serverType === MediaServerType.JELLYFIN
|
|
||||||
? UserType.JELLYFIN
|
|
||||||
: UserType.EMBY;
|
|
||||||
|
|
||||||
await userRepository.save(user);
|
// User doesn't exist, and there are no users in the database, we'll create the user
|
||||||
|
// with admin permissions
|
||||||
|
switch (body.serverType) {
|
||||||
|
case MediaServerType.EMBY:
|
||||||
|
settings.main.mediaServerType = MediaServerType.EMBY;
|
||||||
|
user = new User({
|
||||||
|
email: body.email || account.User.Name,
|
||||||
|
jellyfinUsername: account.User.Name,
|
||||||
|
jellyfinUserId: account.User.Id,
|
||||||
|
jellyfinDeviceId: deviceId,
|
||||||
|
jellyfinAuthToken: account.AccessToken,
|
||||||
|
permissions: Permission.ADMIN,
|
||||||
|
avatar: `/avatarproxy/${account.User.Id}`,
|
||||||
|
userType: UserType.EMBY,
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MediaServerType.JELLYFIN:
|
||||||
|
settings.main.mediaServerType = MediaServerType.JELLYFIN;
|
||||||
|
user = new User({
|
||||||
|
email: body.email || account.User.Name,
|
||||||
|
jellyfinUsername: account.User.Name,
|
||||||
|
jellyfinUserId: account.User.Id,
|
||||||
|
jellyfinDeviceId: deviceId,
|
||||||
|
jellyfinAuthToken: account.AccessToken,
|
||||||
|
permissions: Permission.ADMIN,
|
||||||
|
avatar: `/avatarproxy/${account.User.Id}`,
|
||||||
|
userType: UserType.JELLYFIN,
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('select_server_type');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an API key on Jellyfin from this admin user
|
// Create an API key on Jellyfin from this admin user
|
||||||
@@ -398,6 +368,8 @@ authRoutes.post('/jellyfin', async (req, res, next) => {
|
|||||||
settings.jellyfin.apiKey = apiKey;
|
settings.jellyfin.apiKey = apiKey;
|
||||||
await settings.save();
|
await settings.save();
|
||||||
startJobs();
|
startJobs();
|
||||||
|
|
||||||
|
await userRepository.save(user);
|
||||||
}
|
}
|
||||||
// User already exists, let's update their information
|
// User already exists, let's update their information
|
||||||
else if (account.User.Id === user?.jellyfinUserId) {
|
else if (account.User.Id === user?.jellyfinUserId) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const BlacklistModal = ({
|
|||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const { data, error } = useSWR<TvDetails | MovieDetails>(
|
const { data, error } = useSWR<TvDetails | MovieDetails>(
|
||||||
show ? `/api/v1/${type}/${tmdbId}` : null
|
`/api/v1/${type}/${tmdbId}`
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -82,17 +82,10 @@ const JellyfinLogin: React.FC<JellyfinLoginProps> = ({
|
|||||||
port: Yup.number().required(
|
port: Yup.number().required(
|
||||||
intl.formatMessage(messages.validationPortRequired)
|
intl.formatMessage(messages.validationPortRequired)
|
||||||
),
|
),
|
||||||
urlBase: Yup.string()
|
urlBase: Yup.string().matches(
|
||||||
.test(
|
/^(.*[^/])$/,
|
||||||
'leading-slash',
|
intl.formatMessage(messages.validationUrlBaseTrailingSlash)
|
||||||
intl.formatMessage(messages.validationUrlBaseLeadingSlash),
|
),
|
||||||
(value) => !value || value.startsWith('/')
|
|
||||||
)
|
|
||||||
.test(
|
|
||||||
'trailing-slash',
|
|
||||||
intl.formatMessage(messages.validationUrlBaseTrailingSlash),
|
|
||||||
(value) => !value || !value.endsWith('/')
|
|
||||||
),
|
|
||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
.email(intl.formatMessage(messages.validationemailformat))
|
.email(intl.formatMessage(messages.validationemailformat))
|
||||||
.required(intl.formatMessage(messages.validationemailrequired)),
|
.required(intl.formatMessage(messages.validationemailrequired)),
|
||||||
|
|||||||
Reference in New Issue
Block a user