Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

OpenID authentication support #48

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Make a file called `config.json`, with the following properties:
"rawPasteAgents": "^(?:computercraft|curl|wget)"
}
```

- `logo` - Filenames of your logos images. Make sure to put them in /public.
- `name` - Name of your file host.
- `app_name` - Shortened name of your file host used in app.
Expand All @@ -62,6 +63,11 @@ Make a file called `config.json`, with the following properties:
- `videoFiles` Array of file extentions that shitty will treat as video.
- `languagePackages` Array of npm package names containing atom language grammars.
- `rawPasteAgents` Regular expression (case-insensitive) matching agents to return raw pastes for (on `/paste` and `/edit`). Use `null` to disable.
- `oidcUrl` Base URL for your OpenID Connect host. It uses OpenID Connect Discovery to find the settings. OIDC is optional.
- `oidcClientId` OpenID Connect client id.
- `oidcClientSecret` OpenID Connect client secret.
- `oidcScopes` Scopes to request from the OpenID Connect server.
- `oidcProviderName` Frontend name for the login link

## Custom names

Expand All @@ -85,4 +91,4 @@ More examples for custom naming functions can be found in the [examples director

* Ensure that the user you run the shitty.dl process as has write permissions to `imagePath`.
* Make sure your paste theme has the same scheme as your site - i.e. if your site is HTTPS, the theme must be HTTPS too.
* When running shitty.dl it is suggested to set `NODE_ENV=production` environmental variable to ensure any errors that might happen are not passed on in detail to end user.
* When running shitty.dl it is suggested to set `NODE_ENV=production` environmental variable to ensure any errors that might happen are not passed on in detail to end user.
48 changes: 46 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const helpers = require("handlebars-helpers")();
const dateformat = require("helper-dateformat");
const Finder = require("fs-finder");
const moment = require("moment");
const openidClient = require("openid-client");

const paginator = new require("paginator")(48, 8);
const crypto = require("crypto");
Expand Down Expand Up @@ -128,7 +129,7 @@ const imageFilesFilter = _.map(config.imageFiles,(v)=>"."+v).join(",");
const audioFilesFilter = _.map(config.audioFiles,(v)=>"."+v).join(",");
const videoFilesFilter = _.map(config.videoFiles,(v)=>"."+v).join(",");
const galleryMask = "*.<("+config.imageFiles.concat(config.audioFiles,config.videoFiles).join("|")+")$>";

let nonces = {};
let noncesLookup = {};

Expand All @@ -139,6 +140,19 @@ if (fs.existsSync("custom-name.js")) {
customName = require("./custom-name.js");
}

let oidcClient;
(async() => {
const oidcIssuer = config.oidcUrl && await openidClient.Issuer.discover(config.oidcUrl);
oidcClient = new oidcIssuer.Client({
client_id: config.oidcClientId,
client_secret: config.oidcClientSecret,
redirect_uris: [config.url + "oidc/callback"],
response_types: ["code"],
token_endpoint_auth_method: "client_secret_post",
});
})()
const oidcStateMap = new Map();

if (fs.existsSync("stats.json")) {
try {
statCache = JSON.parse(fs.readFileSync("stats.json"));
Expand Down Expand Up @@ -413,7 +427,9 @@ router.get(["/", "/home"], (req, res) => {
title: conf.title,
disclaimer: conf.disclaimer,
authed: req.session && req.session.authed,
pathname
pathname,
oidc: !!oidcClient,
oidcProviderName: conf.oidcProviderName
});
});

Expand All @@ -428,6 +444,34 @@ router.post("/login", (req, res) => {
res.redirect(pathname+"gallery");
});

router.get("/oidc/redirect", (req, res) => {
if (!oidcClient) return error(req, res, "OIDC not configured");
const state = Math.random().toString(36).slice(2, 7);
Erb3 marked this conversation as resolved.
Show resolved Hide resolved
oidcStateMap.set(req.headers["X-Forwarded-For"] || req.ip, state);
Erb3 marked this conversation as resolved.
Show resolved Hide resolved
res.redirect(oidcClient.authorizationUrl({
scope: config.oidcScopes,
state
}));
})

router.get("/oidc/callback", async (req, res) => {
if (!oidcClient) return error(req, res, "OIDC not configured");

try {
const params = oidcClient.callbackParams(req.url);
await oidcClient.callback(config.url + "/oidc/callback", params, {
state: oidcStateMap.get(req.headers["X-Forwarded-For"] || req.ip)
});

req.session.authed = true;
req.session.save();

res.redirect(pathname+"gallery");
} catch(e) {
return error(req, res, "OIDC authentication failed");
}
})

router.get(["/upload","/webshareupload"], auth, (req, res) => {
const conf = req.config;
res.render("upload", {
Expand Down
Loading