mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
docs
This commit is contained in:
@@ -651,7 +651,7 @@ export default class PostgresSearchProvider extends BaseSearchProvider {
|
||||
|
||||
const filter = options.filter;
|
||||
|
||||
// Visibility predicate for User contexts. A row is visible if any of:
|
||||
// A document is visible if any of:
|
||||
//
|
||||
// - direct membership on the document
|
||||
// - group membership on the document
|
||||
@@ -663,12 +663,6 @@ export default class PostgresSearchProvider extends BaseSearchProvider {
|
||||
// - the user is the creator AND the doc has no collection (unplaced
|
||||
// drafts that no membership/collection check can reach)
|
||||
//
|
||||
// This is load-bearing for authorization. Do not derive the collection
|
||||
// arm from the filter's collectionId leaves — that's the OR-bypass that
|
||||
// broke `documents.list`. Authorization for any collectionId referenced
|
||||
// in the filter has already been enforced by `authorizeFilterFields` in
|
||||
// the route handler; this clause is the safety net.
|
||||
//
|
||||
// For Team contexts (share-based search), the caller is privileged and
|
||||
// has done its own authorization — narrow to the filter's collectionId
|
||||
// if specified, otherwise to the team's publicly-permissioned set.
|
||||
|
||||
@@ -52,9 +52,6 @@ const COMPARISON_OPERATORS = new Set<ComparisonOperator>([
|
||||
* relative-past durations (`-P7D` → `now() - 7 days`) and relative-future
|
||||
* durations (`P7D` → `now() + 7 days`).
|
||||
*
|
||||
* The duration is regex-validated to contain only `P`, `T`, digits, and the
|
||||
* unit letters `YMWDHS`, so the literal interpolation is safe by construction.
|
||||
*
|
||||
* @param duration an ISO 8601 duration, optionally signed with a leading `-`.
|
||||
* @returns a Sequelize literal that resolves to `now() ± interval '<duration>'`.
|
||||
* @throws if the input is not a valid ISO 8601 duration.
|
||||
|
||||
@@ -225,9 +225,9 @@ router.post(
|
||||
|
||||
// Exclude archived docs by default. Suppressed when the caller targets a
|
||||
// specific status, or when their filter already references archivedAt.
|
||||
const filterMentionsArchivedAt =
|
||||
const filterIncludesArchivedAt =
|
||||
filter !== undefined && hasFieldInFilter(filter, "archivedAt");
|
||||
if (!statusFilter && !filterMentionsArchivedAt) {
|
||||
if (!statusFilter && !filterIncludesArchivedAt) {
|
||||
where[Op.and].push({ archivedAt: { [Op.eq]: null } });
|
||||
}
|
||||
|
||||
@@ -259,14 +259,6 @@ router.post(
|
||||
where[Op.and].push(buildWhere<Document>(mapped));
|
||||
}
|
||||
|
||||
// Visibility predicate: a row is visible to the user if it lives in a
|
||||
// collection they can access, or if it is one of their own unplaced
|
||||
// drafts (collectionId is null). This is load-bearing for authorization
|
||||
// — do not skip it based on what the filter "looks like", because under
|
||||
// OR semantics any apparent narrowing collapses. The only exceptions are
|
||||
// the backlink lookup (which scopes by `id` to relationship-derived
|
||||
// documents) and the parent-doc membership escape (which intentionally
|
||||
// surfaces children of an accessible parent across collection boundaries).
|
||||
if (!backlinkDocumentId && !collectionScopeDropped) {
|
||||
const collectionIds = await user.collectionIds();
|
||||
where[Op.and].push({
|
||||
|
||||
Reference in New Issue
Block a user