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 all commits
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.
49 changes: 47 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 @@ -260,6 +274,7 @@ app.use(session({
resave: false,
saveUninitialized: false
}));
app.set("trust proxy", ["loopback", "linklocal", "uniquelocal"]);

bb.extend(app, {
upload: true
Expand Down Expand Up @@ -413,7 +428,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 +445,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 = crypto.randomBytes(8).toString("hex");
oidcStateMap.set(req.ip, state);
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.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