mirror of
https://github.com/wukko/cobalt.git
synced 2024-11-15 04:39:58 +00:00
api/core: implement authentication with api keys
This commit is contained in:
parent
dcd33803c1
commit
81818f8741
1 changed files with 35 additions and 3 deletions
|
@ -17,6 +17,7 @@ import { verifyTurnstileToken } from "../security/turnstile.js";
|
|||
import { friendlyServiceName } from "../processing/service-alias.js";
|
||||
import { verifyStream, getInternalStream } from "../stream/manage.js";
|
||||
import { createResponse, normalizeRequest, getIP } from "../processing/request.js";
|
||||
import * as APIKeys from "../security/api-keys.js";
|
||||
|
||||
const git = {
|
||||
branch: await getBranch(),
|
||||
|
@ -78,7 +79,7 @@ export const runAPI = (express, app, __dirname) => {
|
|||
|
||||
const apiLimiter = rateLimit({
|
||||
windowMs: env.rateLimitWindow * 1000,
|
||||
max: env.rateLimitMax,
|
||||
max: (req) => req.rateLimitMax || env.rateLimitMax,
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false,
|
||||
keyGenerator: req => req.rateLimitKey || generateHmac(getIP(req), ipSalt),
|
||||
|
@ -87,10 +88,10 @@ export const runAPI = (express, app, __dirname) => {
|
|||
|
||||
const apiTunnelLimiter = rateLimit({
|
||||
windowMs: env.rateLimitWindow * 1000,
|
||||
max: env.rateLimitMax,
|
||||
max: (req) => req.rateLimitMax || env.rateLimitMax,
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false,
|
||||
keyGenerator: req => generateHmac(getIP(req), ipSalt),
|
||||
keyGenerator: req => req.rateLimitKey || generateHmac(getIP(req), ipSalt),
|
||||
handler: (req, res) => {
|
||||
return res.sendStatus(429)
|
||||
}
|
||||
|
@ -119,6 +120,33 @@ export const runAPI = (express, app, __dirname) => {
|
|||
next();
|
||||
});
|
||||
|
||||
app.post('/', (req, res, next) => {
|
||||
if (!env.apiKeyURL) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const { success, error } = APIKeys.validateAuthorization(req);
|
||||
if (!success) {
|
||||
// We call next() here if either if:
|
||||
// a) we have user sessions enabled, meaning the request
|
||||
// will still need a Bearer token to not be rejected, or
|
||||
// b) we do not require the user to be authenticated, and
|
||||
// so they can just make the request with the regular
|
||||
// rate limit configuration;
|
||||
// otherwise, we reject the request.
|
||||
if (
|
||||
(env.sessionEnabled || !env.authRequired)
|
||||
&& ['missing', 'not_api_key'].includes(error)
|
||||
) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return fail(res, `error.api.auth.key.${error}`);
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
app.post('/', (req, res, next) => {
|
||||
if (!env.sessionEnabled) {
|
||||
return next();
|
||||
|
@ -315,6 +343,10 @@ export const runAPI = (express, app, __dirname) => {
|
|||
setGlobalDispatcher(new ProxyAgent(env.externalProxy))
|
||||
}
|
||||
|
||||
if (env.apiKeyURL) {
|
||||
APIKeys.setup(env.apiKeyURL);
|
||||
}
|
||||
|
||||
app.listen(env.apiPort, env.listenAddress, () => {
|
||||
console.log(`\n` +
|
||||
Bright(Cyan("cobalt ")) + Bright("API ^ω^") + "\n" +
|
||||
|
|
Loading…
Reference in a new issue