Files
outline/shared/helpers/AuthenticationHelper.ts
T
Tom Moor adbffc0734 chore: clear mechanical lint warnings (Phase 1) (#12198)
* chore: clear mechanical lint warnings

Drops 44 oxlint warnings (559 → 515) by fixing easy mechanical rules
across the codebase: no-useless-escape, no-duplicate-type-constituents,
no-redundant-type-constituents, no-unused-expressions,
no-meaningless-void-operator, require-array-sort-compare, await-thenable.

* chore: drop callback parameter from useCallback deps

The `open` argument is a parameter of the callback, not a closed-over
variable, so it doesn't belong in the deps array.

* chore: promote cleared lint rules to errors

Promotes the rules cleared in this PR from warn to error so future
violations fail the lint:

- no-unused-expressions
- typescript/await-thenable
- typescript/no-duplicate-type-constituents
- typescript/no-meaningless-void-operator
- typescript/require-array-sort-compare

Removes the override that suppressed no-useless-escape on source
files (the global rule is already error) and fixes the 21 escape
violations that this exposed in regex character classes and template
literals.

* chore: address PR review feedback

- usePinnedDocuments: simplify UrlId to plain string instead of the
  intersection trick.
- PlantUML embed: move - to end of character class so it's a literal
  hyphen rather than a range operator.
- checkboxes: type token params as Token | undefined to match the
  actual call sites that pass tokens[index - 2] etc.
2026-04-28 20:00:03 -04:00

70 lines
2.0 KiB
TypeScript

import { Scope } from "../types";
export default class AuthenticationHelper {
/**
* The mapping of method names to their scopes, anything not listed here
* defaults to `Scope.Write`.
*
* - `documents.create` -> `Scope.Create`
* - `documents.list` -> `Scope.Read`
* - `documents.info` -> `Scope.Read`
*/
private static methodToScope = {
create: Scope.Create,
config: Scope.Read,
list: Scope.Read,
info: Scope.Read,
search: Scope.Read,
documents: Scope.Read,
drafts: Scope.Read,
viewed: Scope.Read,
export: Scope.Read,
};
/**
* Returns whether the given path can be accessed with any of the scopes. We
* support scopes in the formats of:
*
* - `/api/namespace.method`
* - `namespace:scope`
* - `scope`
*
* @param path The path to check
* @param scopes The scopes to check
* @returns True if the path can be accessed
*/
public static canAccess = (path: string, scopes: string[]) => {
// A wildcard scope grants full access (e.g. API key with no restrictions)
if (scopes.includes("*")) {
return true;
}
// strip any query string, this is never used as part of scope matching
path = path.split("?")[0];
const resource = path.split("/").pop() ?? "";
const [namespace, method] = resource.split(".");
return scopes.some((scope) => {
const [scopeNamespace, scopeMethod] = scope.match(/[:.]/g)
? scope.replace("/api/", "").split(/[:.]/g)
: ["*", scope];
const isRouteScope = scope.startsWith("/api/");
if (isRouteScope) {
return (
(namespace === scopeNamespace || scopeNamespace === "*") &&
(method === scopeMethod || scopeMethod === "*")
);
}
return (
(namespace === scopeNamespace || scopeNamespace === "*") &&
(scopeMethod === Scope.Write ||
this.methodToScope[method as keyof typeof this.methodToScope] ===
scopeMethod)
);
});
};
}