Feat/oauth2 (#6281): Added oauth to API paths

* Added oauth provider.

* Fixed provider.

* Added auth flow.

* Fixed auth flow and added scaffolding vite config.

* Added working oauth2.

* Fixed dockerfile.

* Adapted run.sh script

* Moved api tests to oauth2.

* Updated security schemes.

* Removed api key from existance.

* Fixed installation

* Added missing issuer in config.

* Fixed dev dependencies.

* Updated lock file.
This commit is contained in:
SamTV12345 2024-03-26 17:11:24 +01:00 committed by GitHub
parent 562177022f
commit fb56809e55
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 1782 additions and 237 deletions

View file

@ -21,30 +21,12 @@
import {MapArrayType} from "../types/MapType";
const absolutePaths = require('../utils/AbsolutePaths');
import fs from 'fs';
const api = require('../db/API');
import log4js from 'log4js';
const padManager = require('../db/PadManager');
const randomString = require('../utils/randomstring');
const argv = require('../utils/Cli').argv;
import createHTTPError from 'http-errors';
const apiHandlerLogger = log4js.getLogger('APIHandler');
// ensure we have an apikey
let apikey:string|null = null;
const apikeyFilename = absolutePaths.makeAbsolute(argv.apikey || './APIKEY.txt');
try {
apikey = fs.readFileSync(apikeyFilename, 'utf8');
apiHandlerLogger.info(`Api key file read from: "${apikeyFilename}"`);
} catch (e) {
apiHandlerLogger.info(
`Api key file "${apikeyFilename}" not found. Creating with random contents.`);
apikey = randomString(32);
fs.writeFileSync(apikeyFilename, apikey!, 'utf8');
}
import {Http2ServerRequest, Http2ServerResponse} from "node:http2";
import {publicKeyExported} from "../security/OAuth2Provider";
import {jwtVerify} from "jose";
// a list of all functions
const version:MapArrayType<any> = {};
@ -167,21 +149,20 @@ exports.version = version;
type APIFields = {
apikey: string;
api_key: string;
padID: string;
padName: string;
}
/**
* Handles a HTTP API call
* Handles an HTTP API call
* @param {String} apiVersion the version of the api
* @param {String} functionName the name of the called function
* @param fields the params of the called function
* @req express request object
* @res express response object
* @param req express request object
* @param res express response object
*/
exports.handle = async function (apiVersion: string, functionName: string, fields: APIFields) {
exports.handle = async function (apiVersion: string, functionName: string, fields: APIFields, req: Http2ServerRequest, res: Http2ServerResponse) {
// say goodbye if this is an unknown API version
if (!(apiVersion in version)) {
throw new createHTTPError.NotFound('no such api version');
@ -192,13 +173,20 @@ exports.handle = async function (apiVersion: string, functionName: string, field
throw new createHTTPError.NotFound('no such function');
}
// check the api key!
fields.apikey = fields.apikey || fields.api_key;
if (fields.apikey !== apikey!.trim()) {
if(!req.headers.authorization) {
throw new createHTTPError.Unauthorized('no or wrong API Key');
}
try {
await jwtVerify(req.headers.authorization!.replace("Bearer ", ""), publicKeyExported!, {algorithms: ['RS256'],
requiredClaims: ["admin"]})
} catch (e) {
throw new createHTTPError.Unauthorized('no or wrong API Key');
}
// sanitize any padIDs before continuing
if (fields.padID) {
fields.padID = await padManager.sanitizePadId(fields.padID);
@ -217,7 +205,3 @@ exports.handle = async function (apiVersion: string, functionName: string, field
// call the api function
return api[functionName].apply(this, functionParams);
};
exports.exportedForTestingOnly = {
apiKey: apikey,
};