mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #36767 from overleaf/oa-express-types
[web] Express req/res/next types GitOrigin-RevId: 30b4822e2ee55976331d049f8109f7098914973c
This commit is contained in:
@@ -26,9 +26,9 @@ const {
|
||||
*/
|
||||
function useCapabilities() {
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
const middleware = async function (req, res, next) {
|
||||
// attach the user's capabilities to the request object
|
||||
@@ -36,7 +36,7 @@ function useCapabilities() {
|
||||
// provide a function to assert that a capability is present
|
||||
/** @param {any} capability */
|
||||
req.assertPermission = capability => {
|
||||
if (!req.capabilitySet.has(capability)) {
|
||||
if (!req.capabilitySet?.has(capability)) {
|
||||
throw new ForbiddenError(
|
||||
`user does not have permission for ${capability}`
|
||||
)
|
||||
@@ -64,15 +64,17 @@ function useCapabilities() {
|
||||
const combinedGroupPolicy = combineGroupPolicies(groupPolicies)
|
||||
// attach the new capabilities to the request object
|
||||
for (const cap of getUserCapabilities(combinedGroupPolicy)) {
|
||||
req.capabilitySet.add(cap)
|
||||
req.capabilitySet?.add(cap)
|
||||
}
|
||||
// also attach the user's restrictions (the capabilities they don't have)
|
||||
req.userRestrictions = getUserRestrictions(combinedGroupPolicy)
|
||||
|
||||
// attach allowed properties to the request object
|
||||
const allowedProperties = combineAllowedProperties(results)
|
||||
/** @type {Record<string, any>} */
|
||||
const reqRecord = req
|
||||
for (const [prop, value] of Object.entries(allowedProperties)) {
|
||||
req[prop] = value
|
||||
reqRecord[prop] = value
|
||||
}
|
||||
}
|
||||
next()
|
||||
|
||||
@@ -10,6 +10,12 @@ import Errors from '../Errors/Errors.js'
|
||||
import { preparePlainTextResponse } from '../../infrastructure/Response.mjs'
|
||||
import { z, zz, parseReq } from '../../infrastructure/Validation.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
const getFileSchema = z.object({
|
||||
params: z.strictObject({
|
||||
Project_id: zz.objectId(),
|
||||
@@ -28,8 +34,8 @@ const getFileHeadSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function getFile(req, res) {
|
||||
const { params, query } = parseReq(req, getFileSchema, { logOnly: true })
|
||||
@@ -125,8 +131,8 @@ async function getFile(req, res) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function getFileHead(req, res) {
|
||||
const { params } = parseReq(req, getFileHeadSchema, { logOnly: true })
|
||||
|
||||
@@ -35,6 +35,12 @@ import { z, zz, parseReq } from '../../infrastructure/Validation.mjs'
|
||||
/** @type {any} */
|
||||
import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
// Number of seconds after which the browser should send a request to revalidate
|
||||
// blobs
|
||||
const REVALIDATE_BLOB_AFTER_SECONDS = 86400 // 1 day
|
||||
@@ -46,16 +52,16 @@ const STALE_WHILE_REVALIDATE_SECONDS = 365 * 86400 // 1 year
|
||||
const MAX_HISTORY_ZIP_ATTEMPTS = 40
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function getBlob(req, res) {
|
||||
await requestBlob('GET', req, res)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function headBlob(req, res) {
|
||||
await requestBlob('HEAD', req, res)
|
||||
@@ -73,8 +79,8 @@ const requestBlobSchema = z.object({
|
||||
|
||||
/**
|
||||
* @param {any} method
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function requestBlob(method, req, res) {
|
||||
const { params } = parseReq(req, requestBlobSchema)
|
||||
@@ -124,7 +130,7 @@ async function requestBlob(method, req, res) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} res
|
||||
* @param {Response} res
|
||||
* @param {any} etag
|
||||
*/
|
||||
function setBlobCacheHeaders(res, etag) {
|
||||
@@ -159,9 +165,9 @@ const proxyToHistoryApiFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function proxyToHistoryApi(req, res, next) {
|
||||
parseReq(req, proxyToHistoryApiSchema, {
|
||||
@@ -210,9 +216,9 @@ const proxyToHistoryApiAndInjectUserDetailsFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function proxyToHistoryApiAndInjectUserDetails(req, res, next) {
|
||||
parseReq(req, proxyToHistoryApiAndInjectUserDetailsSchema, {
|
||||
@@ -251,9 +257,9 @@ const resyncProjectHistoryFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function resyncProjectHistory(req, res, next) {
|
||||
// increase timeout to 6 minutes
|
||||
@@ -306,9 +312,9 @@ const restoreFileFromV2FallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function restoreFileFromV2(req, res, next) {
|
||||
const { params, body } = parseReq(req, restoreFileFromV2Schema, {
|
||||
@@ -367,9 +373,9 @@ const revertFileFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function revertFile(req, res, next) {
|
||||
const { params, body } = parseReq(req, revertFileSchema, {
|
||||
@@ -427,9 +433,9 @@ const revertProjectFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function revertProject(req, res, next) {
|
||||
const { params, body } = parseReq(req, revertProjectSchema, {
|
||||
@@ -475,9 +481,9 @@ const getLabelsFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function getLabels(req, res, next) {
|
||||
const { params } = parseReq(req, getLabelsSchema, {
|
||||
@@ -516,9 +522,9 @@ const createLabelFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function createLabel(req, res, next) {
|
||||
const { params, body } = parseReq(req, createLabelSchema, {
|
||||
@@ -636,9 +642,9 @@ const deleteLabelFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function deleteLabel(req, res, next) {
|
||||
const { params } = parseReq(req, deleteLabelSchema, {
|
||||
@@ -672,9 +678,9 @@ const downloadZipOfVersionSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function downloadZipOfVersion(req, res, next) {
|
||||
const { params } = parseReq(req, downloadZipOfVersionSchema)
|
||||
@@ -718,8 +724,8 @@ async function downloadZipOfVersion(req, res, next) {
|
||||
* @param {any} v1ProjectId
|
||||
* @param {any} version
|
||||
* @param {any} name
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function _pipeHistoryZipToResponse(v1ProjectId, version, name, req, res) {
|
||||
if (req.destroyed) {
|
||||
@@ -837,9 +843,9 @@ const getLatestHistorySchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function getLatestHistory(req, res, next) {
|
||||
const { params } = parseReq(req, getLatestHistorySchema)
|
||||
@@ -859,9 +865,9 @@ const getChangesSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function getChanges(req, res, next) {
|
||||
const { params, query } = parseReq(req, getChangesSchema)
|
||||
|
||||
@@ -131,7 +131,7 @@ const _buildPortalTemplatesList = affiliations => {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {import("express").Request} req
|
||||
*/
|
||||
function cleanupSession(req) {
|
||||
// cleanup redirects at the end of the redirect chain
|
||||
|
||||
@@ -4,6 +4,12 @@ import SessionManager from '../Authentication/SessionManager.mjs'
|
||||
import LearnedWordsManager from './LearnedWordsManager.mjs'
|
||||
import { z, parseReq } from '../../infrastructure/Validation.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
const learnSchema = z.object({
|
||||
body: z.strictObject({
|
||||
word: z.string().min(1),
|
||||
@@ -32,9 +38,9 @@ const unlearnFallbackSchema = z.object({
|
||||
|
||||
export default {
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
learn(req, res, next) {
|
||||
const { body } = parseReq(req, learnSchema, {
|
||||
@@ -53,9 +59,9 @@ export default {
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
unlearn(req, res, next) {
|
||||
const { body } = parseReq(req, unlearnSchema, {
|
||||
|
||||
@@ -41,6 +41,9 @@ const SUBSCRIPTION_PAUSED_REDIRECT_PATH =
|
||||
* @typedef {import('../../../../types/subscription/currency').CurrencyCode} CurrencyCode
|
||||
* @typedef {import('./PaymentProviderEntities.mjs').PaymentProviderSubscription} PaymentProviderSubscription
|
||||
* @typedef {import('../../../../types/subscription/plan').Plan} Plan
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -161,8 +164,8 @@ const userSubscriptionPageSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function userSubscriptionPage(req, res) {
|
||||
const { query } = parseReq(req, userSubscriptionPageSchema, {
|
||||
@@ -378,8 +381,8 @@ const successfulSubscriptionFallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function successfulSubscription(req, res) {
|
||||
const { query } = parseReq(req, successfulSubscriptionSchema, {
|
||||
@@ -431,9 +434,9 @@ const pauseSubscriptionSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function pauseSubscription(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -487,9 +490,9 @@ async function pauseSubscription(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function resumeSubscription(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -508,9 +511,9 @@ async function resumeSubscription(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function cancelSubscription(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -527,12 +530,10 @@ async function cancelSubscription(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @returns {Promise<void>}
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function canceledSubscription(req, res, next) {
|
||||
async function canceledSubscription(req, res) {
|
||||
return res.render('subscriptions/canceled-subscription-react', {
|
||||
title: 'subscription_canceled',
|
||||
user: sanitizeSessionUserForFrontEnd(
|
||||
@@ -542,9 +543,9 @@ async function canceledSubscription(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function cancelV1Subscription(req, res, next) {
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
@@ -570,8 +571,8 @@ const previewAddonPurchaseSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function previewAddonPurchase(req, res) {
|
||||
const { params } = parseReq(req, previewAddonPurchaseSchema, {
|
||||
@@ -589,11 +590,10 @@ async function previewAddonPurchase(req, res) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function purchaseAddon(req, res, next) {
|
||||
async function purchaseAddon(req, res) {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
@@ -604,9 +604,9 @@ const removeAddonSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function removeAddon(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -662,8 +662,8 @@ const reactivateAddonSchema = z.object({
|
||||
* Reactivate an add-on pending cancellation
|
||||
*
|
||||
* This "cancels" the cancellation.
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function reactivateAddon(req, res) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -701,11 +701,10 @@ const previewSubscriptionSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function previewSubscription(req, res, next) {
|
||||
async function previewSubscription(req, res) {
|
||||
const { query } = parseReq(req, previewSubscriptionSchema, {
|
||||
logOnly: true,
|
||||
})
|
||||
@@ -768,9 +767,9 @@ async function previewSubscription(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function cancelPendingSubscriptionChange(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -794,9 +793,9 @@ function cancelPendingSubscriptionChange(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function updateAccountEmailAddress(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -813,9 +812,9 @@ async function updateAccountEmailAddress(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function reactivateSubscription(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -859,9 +858,9 @@ const recurlyCallbackSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function recurlyCallback(req, res, next) {
|
||||
const { body } = parseReq(req, recurlyCallbackSchema, { logOnly: true })
|
||||
@@ -914,8 +913,8 @@ function recurlyCallback(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function extendTrial(req, res) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -943,9 +942,9 @@ async function extendTrial(req, res) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function recurlyNotificationParser(req, res, next) {
|
||||
let xml = ''
|
||||
@@ -975,8 +974,8 @@ const refreshUserFeaturesSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function refreshUserFeatures(req, res) {
|
||||
const { params } = parseReq(req, refreshUserFeaturesSchema, {
|
||||
@@ -1003,8 +1002,8 @@ const getRecommendedCurrencySchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @returns {Promise<{currency: CurrencyCode, recommendedCurrency: CurrencyCode, countryCode: string|undefined}>}
|
||||
*/
|
||||
async function getRecommendedCurrency(req, res) {
|
||||
@@ -1049,8 +1048,8 @@ const getLatamCountryBannerDetailsSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function getLatamCountryBannerDetails(req, res) {
|
||||
const { query } = parseReq(req, getLatamCountryBannerDetailsSchema, {
|
||||
|
||||
@@ -236,7 +236,7 @@ async function syncSubscription(recurlySubscription, requesterData) {
|
||||
/**
|
||||
* attempt to collect past due invoice for customer. Only do that when a) the
|
||||
* customer is using Paypal and b) there is only one past due invoice.
|
||||
* This is used because Recurly doesn't always attempt collection of paast due
|
||||
* This is used because Recurly doesn't always attempt collection of past due
|
||||
* invoices after Paypal billing info were updated.
|
||||
*
|
||||
* @param {any} recurlyAccountCode
|
||||
|
||||
@@ -19,6 +19,12 @@ import UserAuditLogHandler from '../User/UserAuditLogHandler.mjs'
|
||||
import { sanitizeSessionUserForFrontEnd } from '../../infrastructure/FrontEndUser.mjs'
|
||||
import { z, zz, parseReq } from '../../infrastructure/Validation.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
const rateLimiters = {
|
||||
resendGroupInvite: new RateLimiter('resend-group-invite', {
|
||||
points: 1,
|
||||
@@ -33,9 +39,9 @@ const createInviteSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function createInvite(req, res, next) {
|
||||
const { body } = parseReq(req, createInviteSchema, { logOnly: true })
|
||||
@@ -96,9 +102,9 @@ const viewInviteSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function viewInvite(req, res, next) {
|
||||
const { params, query } = parseReq(req, viewInviteSchema, {
|
||||
@@ -220,9 +226,9 @@ async function viewInvite(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function viewInvites(req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
@@ -246,9 +252,9 @@ const acceptInviteSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function acceptInvite(req, res, next) {
|
||||
const { params } = parseReq(req, acceptInviteSchema, { logOnly: true })
|
||||
@@ -294,9 +300,9 @@ const revokeInviteSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function revokeInvite(req, res, next) {
|
||||
const { params } = parseReq(req, revokeInviteSchema, { logOnly: true })
|
||||
@@ -331,9 +337,9 @@ const resendInviteSchema = z.object({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async function resendInvite(req, res, next) {
|
||||
const { body } = parseReq(req, resendInviteSchema, { logOnly: true })
|
||||
|
||||
@@ -23,6 +23,12 @@ import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
|
||||
import { multer, multerUploadHandler } from '../../infrastructure/Multer.mjs'
|
||||
import { parseReq, z, zz } from '../../infrastructure/Validation.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
const uploadMetaTypeSchema = z.string().optional()
|
||||
|
||||
const uploadProjectSchema = z.object({
|
||||
@@ -77,11 +83,10 @@ const upload = multerUploadHandler({
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
function uploadProject(req, res, next) {
|
||||
function uploadProject(req, res) {
|
||||
const timer = new metrics.Timer('project-upload')
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
const { body, file } = parseReq(req, uploadProjectSchema, {
|
||||
@@ -120,11 +125,10 @@ function uploadProject(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function uploadFile(req, res, next) {
|
||||
async function uploadFile(req, res) {
|
||||
const timer = new metrics.Timer('file-upload')
|
||||
const { params, query, body, file } = parseReq(req, uploadFileSchema, {
|
||||
logOnly: true,
|
||||
@@ -226,11 +230,10 @@ async function uploadFile(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
async function importDocument(req, res, next) {
|
||||
async function importDocument(req, res) {
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
const { query, body, file } = parseReq(req, importDocumentSchema, {
|
||||
logOnly: true,
|
||||
@@ -313,9 +316,9 @@ async function importDocument(req, res, next) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function multerMiddleware(req, res, next) {
|
||||
if (upload == null) {
|
||||
|
||||
@@ -17,6 +17,12 @@ import {
|
||||
} from '../../infrastructure/Validation.mjs'
|
||||
import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
|
||||
|
||||
/**
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
*/
|
||||
|
||||
const { useAdminCapabilities, useNonAdminDomainCapabilities } =
|
||||
AdminAuthorizationHelper
|
||||
// set of middleware arrays or functions that checks user access to an entity
|
||||
@@ -310,9 +316,9 @@ const requireGraphAccessSchema = z.object({
|
||||
// - the entity name is in `req.query.resource_type` and is used to find the
|
||||
// require middleware depending on the entity name
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
function requireGraphAccess(req, res, next) {
|
||||
const { query, params } = parseReq(req, requireGraphAccessSchema, {
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
import Settings from '@overleaf/settings'
|
||||
|
||||
/**
|
||||
* @import { HttpPermissionsPolicy } from './types'
|
||||
* @typedef {import('express').Request} Request
|
||||
* @typedef {import('express').Response} Response
|
||||
* @typedef {import('express').NextFunction} NextFunction
|
||||
* @typedef {import('./types').HttpPermissionsPolicy} HttpPermissionsPolicy
|
||||
*/
|
||||
|
||||
class HttpPermissionsPolicyMiddleware {
|
||||
@@ -73,16 +76,17 @@ class HttpPermissionsPolicyMiddleware {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} req
|
||||
* @param {any} res
|
||||
* @param {any} next
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
middleware(req, res, next) {
|
||||
if (this.policy && Settings.useHttpPermissionsPolicy) {
|
||||
const policy = this.policy
|
||||
if (policy && Settings.useHttpPermissionsPolicy) {
|
||||
const originalRender = res.render
|
||||
|
||||
res.render = (/** @type {any} */ ...args) => {
|
||||
res.setHeader('Permissions-Policy', this.policy)
|
||||
res.setHeader('Permissions-Policy', policy)
|
||||
originalRender.apply(res, args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import { UserFeatureUsage } from '../../models/UserFeatureUsage.mjs'
|
||||
import { TooManyRequestsError } from '../../Features/Errors/Errors.js'
|
||||
import AnalyticsManager from '../../Features/Analytics/AnalyticsManager.mjs'
|
||||
import UserAuditLogHandler from '../../Features/User/UserAuditLogHandler.mjs'
|
||||
|
||||
/** @typedef {{usage?: number | null, periodStart?: Date | null}} FeatureUsage */
|
||||
/** @typedef {{remainingTokens?: number | null, periodStart?: Date | null}} RemainingTokens */
|
||||
/** @typedef {import('express').Response} Response */
|
||||
|
||||
const PERIOD = 24 // hours
|
||||
const PERIOD_IN_MILLISECONDS = PERIOD * 60 * 60 * 1000
|
||||
@@ -60,7 +62,7 @@ export default class TokenUsageRateLimiter {
|
||||
|
||||
/**
|
||||
* @param {any} userId
|
||||
* @param {any} res
|
||||
* @param {Response} res
|
||||
* @param {any} amount
|
||||
* @param {{ auditLogTool?: string }} [options] - if `auditLogTool` is set, an `ai-quota-breach` audit log entry is written with `{ tool }` in the info payload when this recording crosses or sits past the allowance
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'express'
|
||||
import OAuth2Server from '@node-oauth/oauth2-server'
|
||||
import type SessionData from 'express-session'
|
||||
import type { Capability } from '../../capabilities'
|
||||
|
||||
// Request-scoped logger attached by @overleaf/metrics http.monitor() middleware.
|
||||
// See libraries/metrics/http.js RequestLogger class.
|
||||
@@ -20,11 +21,17 @@ declare module 'express' {
|
||||
oauth_user?: OAuth2Server.User
|
||||
logger: RequestLogger
|
||||
i18n: {
|
||||
language: string
|
||||
translate(
|
||||
key: string,
|
||||
vars?: Record<string, any>,
|
||||
components?: any
|
||||
): string
|
||||
}
|
||||
// Set by PermissionMiddleware
|
||||
managedBy?: any
|
||||
isManagedGroupAdmin?: boolean
|
||||
capabilitySet?: Set<Capability>
|
||||
assertPermission(capability: string): void
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'express'
|
||||
|
||||
declare module 'express' {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
interface Response {
|
||||
// Set per-request by the addSetContentDisposition middleware in
|
||||
// app/src/infrastructure/ExpressLocals.mjs (web/private-api/public-api routers only).
|
||||
setContentDisposition(
|
||||
type: 'attachment' | 'inline',
|
||||
opts: { filename: string }
|
||||
): void
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user