Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OIDC Support - Attempt 2 #3746

Open
wants to merge 33 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2f68fc0
feat: oidc support
ankarhem May 29, 2022
48a58c5
feat: refactor out popup and use for oidc
ankarhem May 30, 2022
aedf99f
feat(oidc): create user if it doesn't exist
ankarhem May 31, 2022
d2ef1be
docs: add api documentation for oidc endpoints
ankarhem May 31, 2022
3ff1007
chore(translations): extract strings
ankarhem May 31, 2022
e42b216
feat(oidc): add form validation for oidc settings
ankarhem May 31, 2022
77fbf63
fix: add missing initial values to public settings
ankarhem May 31, 2022
0e83788
fix(docs): fix typo in docs
ankarhem May 31, 2022
25db52e
fix(oidc): invalidate when email not verified
ankarhem Jun 1, 2022
f1fbd57
fix: review comments
ankarhem Oct 1, 2022
58b043b
fix(imports): fix invalid imports
ankarhem Oct 1, 2022
0bc1326
fix(i18n): update extract
ankarhem Oct 1, 2022
8c2a359
fix: invalid import
ankarhem Oct 1, 2022
d6fcaec
fix(oidc): use wellknown authorization endpoint
ankarhem Oct 11, 2022
2a19002
fix(oidc login): handle reset loading state
ankarhem Oct 11, 2022
c837615
fix(oidc): allow paths in wellknown lookup
ankarhem Oct 11, 2022
eb27d0e
fix(oidc): allow insecure state cookie when using http
ankarhem Oct 11, 2022
487f5c6
fix(oidc): look at protocol to decide callback protocol
ankarhem Oct 12, 2022
4b77110
got oidc working for authelia
Jan 2, 2024
0b950aa
made proggress on oidc with better try catch
Jan 2, 2024
46305ff
blah
Jan 2, 2024
11f30e9
oidc callback logging
Dec 29, 2023
d2f57ae
okay trying again with no error handling changes. Just logging and sc…
Dec 29, 2023
3816f73
scope missing is not a fatal error
Dec 29, 2023
5830fdc
add scope support for oidc
Dec 29, 2023
ecd4537
added additional logging and error handling to try to debug a scope p…
Dec 28, 2023
6da25cd
fix the redirect uri generation to use x-forward-proto to allow handl…
Dec 28, 2023
bcdf95f
add middleare logger back in and debug should not be default logging …
Jan 10, 2024
502b9fb
icon fixes for heroicons v2
Jan 3, 2024
06954a0
Fix New Plex Login option being tied to localLogin settings, and also…
Jan 10, 2024
9b7bd91
rounded corners for plex
Jan 10, 2024
0a5945a
logging and eslint fixes. Prevent log injection and properly import a…
Jan 10, 2024
8216a60
feat(oidc support): add oidc support
Jan 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/extending-overseerr/reverse-proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-';
Expand Down
74 changes: 74 additions & 0 deletions overseerr-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3435,6 +3435,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
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"formik": "2.2.9",
"gravatar-url": "3.1.0",
"intl": "1.2.5",
"jwt-decode": "^3.1.2",
"lodash": "4.17.21",
"next": "12.3.4",
"node-cache": "5.1.2",
Expand Down
35 changes: 35 additions & 0 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import express from 'express';
import * as OpenApiValidator from 'express-openapi-validator';
import type { Store } from 'express-session';
import session from 'express-session';
import _ from 'lodash';
import next from 'next';
import path from 'path';
import swaggerUi from 'swagger-ui-express';
Expand All @@ -43,6 +44,39 @@ const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const logMiddleware = (req: Request, res: Response, next: NextFunction) => {
// Enhanced sanitization function with explicit return type
const sanitize = (input: unknown, depth = 0): string => {
if (depth > 2) {
return typeof input === 'string' ? _.escape(input) : '[Complex Object]';
}
if (typeof input === 'string') {
return _.escape(_.truncate(input, { length: 200 }));
} else if (_.isObject(input)) {
return _.mapValues(input, (value) =>
sanitize(value, depth + 1)
) as unknown as string;
}
return input as string;
};

// Function to selectively log properties with explicit parameter types
const safeLog = (key: string, value: unknown): unknown => {
const sensitiveKeys = ['authorization', 'cookie', 'set-cookie'];
if (sensitiveKeys.includes(key.toLowerCase())) {
return '[Filtered]';
}
return sanitize(value);
};

logger.debug(`Request Method: ${sanitize(req.method)}`);
logger.debug(`Request URL: ${sanitize(req.originalUrl)}`);
logger.debug(`Request Headers: ${JSON.stringify(req.headers, safeLog)}`);
logger.debug(`Request Body: ${JSON.stringify(req.body, safeLog)}`);

next();
};

app
.prepare()
.then(async () => {
Expand Down Expand Up @@ -104,6 +138,7 @@ app
if (settings.main.trustProxy) {
server.enable('trust proxy');
}
server.use(logMiddleware);
server.use(cookieParser());
server.use(express.json());
server.use(express.urlencoded({ extended: true }));
Expand Down
2 changes: 2 additions & 0 deletions server/interfaces/api/settingsInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface PublicSettingsResponse {
locale: string;
emailEnabled: boolean;
newPlexLogin: boolean;
oidcLogin: boolean;
oidcName: string;
}

export interface CacheItem {
Expand Down
14 changes: 14 additions & 0 deletions server/lib/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export interface MainSettings {
hideAvailable: boolean;
localLogin: boolean;
newPlexLogin: boolean;
oidcLogin: boolean;
oidcName: string;
oidcClientId: string;
oidcClientSecret: string;
oidcDomain: string;
region: string;
originalLanguage: string;
trustProxy: boolean;
Expand Down Expand Up @@ -126,6 +131,8 @@ interface FullPublicSettings extends PublicSettings {
locale: string;
emailEnabled: boolean;
newPlexLogin: boolean;
oidcLogin: boolean;
oidcName: string;
}

export interface NotificationAgentConfig {
Expand Down Expand Up @@ -296,6 +303,11 @@ class Settings {
hideAvailable: false,
localLogin: true,
newPlexLogin: true,
oidcLogin: false,
oidcName: '',
oidcClientId: '',
oidcClientSecret: '',
oidcDomain: '',
region: '',
originalLanguage: '',
trustProxy: false,
Expand Down Expand Up @@ -512,6 +524,8 @@ class Settings {
locale: this.data.main.locale,
emailEnabled: this.data.notifications.agents.email.enabled,
newPlexLogin: this.data.main.newPlexLogin,
oidcLogin: this.data.main.oidcLogin,
oidcName: this.data.main.oidcName,
};
}

Expand Down
2 changes: 1 addition & 1 deletion server/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const hformat = winston.format.printf(
);

const logger = winston.createLogger({
level: process.env.LOG_LEVEL?.toLowerCase() || 'debug',
level: process.env.LOG_LEVEL?.toLowerCase() || 'info',
format: winston.format.combine(
winston.format.splat(),
winston.format.timestamp(),
Expand Down
Loading