Protecting some APIs with an APIKEY.
This commit is contained in:
parent
787fed19d0
commit
6b77c3585d
17
server/lib/apikey.ts
Normal file
17
server/lib/apikey.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
For internal API, we will generate an api Key that must be provided as
|
||||
GET parameter for every API call.
|
||||
*/
|
||||
|
||||
async function getAPIKey ({ storageManager }: RegisterServerOptions): Promise<string> {
|
||||
let value: string = await storageManager.getData('APIKEY')
|
||||
if (!value) {
|
||||
value = Math.random().toString(36).slice(2, 12)
|
||||
await storageManager.storeData('APIKEY', value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
export {
|
||||
getAPIKey
|
||||
}
|
21
server/lib/middlewares/apikey.ts
Normal file
21
server/lib/middlewares/apikey.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import type { Request, Response, NextFunction } from 'express'
|
||||
import { getAPIKey } from '../apikey'
|
||||
|
||||
type CheckAPIKeyMiddlewareFunc = (req: Request, res: Response, next: NextFunction) => Promise<void>
|
||||
|
||||
function getCheckAPIKeyMiddleware (options: RegisterServerOptions): CheckAPIKeyMiddlewareFunc {
|
||||
return async (req: Request, res: Response, next: NextFunction) => {
|
||||
const key = req.query.apikey
|
||||
const apikey = await getAPIKey(options)
|
||||
if (key !== apikey) {
|
||||
options.peertubeHelpers.logger.warn('Invalid APIKEY')
|
||||
res.sendStatus(403)
|
||||
return
|
||||
}
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
getCheckAPIKeyMiddleware
|
||||
}
|
@ -3,6 +3,7 @@ import * as path from 'path'
|
||||
import { pluginName, getBaseRouter } from '../helpers'
|
||||
import { ProsodyFilePaths } from './config/paths'
|
||||
import { ProsodyConfigContent } from './config/content'
|
||||
import { getAPIKey } from '../apikey'
|
||||
|
||||
async function getWorkingDir ({ peertubeHelpers, storageManager }: RegisterServerOptions): Promise<string> {
|
||||
const logger = peertubeHelpers.logger
|
||||
@ -94,11 +95,12 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
const peertubeDomain = 'localhost'
|
||||
const paths = await getProsodyFilePaths(options)
|
||||
|
||||
const apikey = await getAPIKey(options)
|
||||
const baseApiUrl = options.peertubeHelpers.config.getWebserverUrl() +
|
||||
getBaseRouter() +
|
||||
'api/'
|
||||
const authApiUrl = baseApiUrl + 'user'
|
||||
const roomApiUrl = baseApiUrl + 'room?jid={room.jid|jid_node}'
|
||||
const authApiUrl = baseApiUrl + 'user' // FIXME: should be protected by apikey, but mod_auth_http cant handle params
|
||||
const roomApiUrl = baseApiUrl + 'room?apikey=' + apikey + '&jid={room.jid|jid_node}'
|
||||
|
||||
const config = new ProsodyConfigContent(paths)
|
||||
config.useHttpAuthentication(authApiUrl)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Router, Request, Response, NextFunction } from 'express'
|
||||
import { videoHasWebchat } from '../../../shared/lib/video'
|
||||
import { asyncMiddleware } from '../middlewares/async'
|
||||
import { getCheckAPIKeyMiddleware } from '../middlewares/apikey'
|
||||
import { prosodyCheckUserPassword, prosodyRegisterUser, prosodyUserRegistered } from '../prosody/auth'
|
||||
import { getAuthUser, getUserNickname } from '../helpers'
|
||||
import { Affiliations, getVideoAffiliations } from '../prosody/config/affiliations'
|
||||
@ -30,7 +31,8 @@ async function initApiRouter (options: RegisterServerOptions): Promise<Router> {
|
||||
const router = getRouter()
|
||||
const logger = peertubeHelpers.logger
|
||||
|
||||
router.get('/room', asyncMiddleware(
|
||||
router.get('/room', asyncMiddleware([
|
||||
getCheckAPIKeyMiddleware(options),
|
||||
async (req: Request, res: Response, _next: NextFunction) => {
|
||||
const jid: string = req.query.jid as string || ''
|
||||
logger.info(`Requesting room information for room '${jid}'.`)
|
||||
@ -85,7 +87,7 @@ async function initApiRouter (options: RegisterServerOptions): Promise<Router> {
|
||||
}
|
||||
res.json(roomDefaults)
|
||||
}
|
||||
))
|
||||
]))
|
||||
|
||||
router.get('/auth', asyncMiddleware(
|
||||
async (req: Request, res: Response, _next: NextFunction) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user