Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions desktop/main/composables/current-page-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export const useCurrentNavigationIndex = (

const currentNavigation = ref(-1);

/**
* Determines the navigation item that best matches a route.
*
* @param to - The route whose path is matched against the navigation prefixes
* @returns The index of the longest matching navigation route, or `-1` when no route matches
*/
function calculateCurrentNavIndex(to: RouteLocationNormalized) {
const validOptions = navigation
.map((e, i) => ({ ...e, index: i }))
Expand Down
2 changes: 1 addition & 1 deletion scripts/sonarcloud-pr-comment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ if ! command -v gh &>/dev/null; then
exit 1
fi

# --- Helpers ------------------------------------------------------------------
# log prints a timestamped message to standard output.

log() { echo "[$(date '+%H:%M:%S')] $*"; }

Expand Down
6 changes: 6 additions & 0 deletions server/composables/current-page-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export const useCurrentNavigationIndex = (

const currentNavigation = ref(-1);

/**
* Determines the navigation item matching the current route.
*
* @param to - The route whose path is matched against the navigation prefixes
* @returns The index of the most specific matching navigation item, or `-1` when no item matches
*/
function calculateCurrentNavIndex(to: typeof route) {
const validOptions = navigation
.map((e, i) => ({ ...e, index: i }))
Expand Down
32 changes: 32 additions & 0 deletions server/server/internal/auth/oidc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ export class OIDCManager {
}
}

/**
* Loads the OIDC provider configuration from a well-known URL or environment variables.
*
* @returns The validated OIDC provider configuration.
*/
async function loadOIDCConfiguration(): Promise<OIDCConfiguration> {
const wellKnownUrlString = process.env.OIDC_WELLKNOWN as string | undefined;
const scopes = process.env.OIDC_SCOPES as string | undefined;
Expand All @@ -474,6 +479,14 @@ async function loadOIDCConfiguration(): Promise<OIDCConfiguration> {
return loadFromEnvVars(scopes);
}

/**
* Loads and validates OIDC provider configuration from a well-known URL.
*
* @param wellKnownUrlString - The OIDC discovery document URL
* @param scopes - Optional comma-separated scopes that override discovered scopes
* @returns The validated OIDC provider configuration
* @throws If the URL or required configuration is invalid, or if HTTPS is required and unavailable
*/
async function loadFromWellKnown(
wellKnownUrlString: string,
scopes: string | undefined,
Expand Down Expand Up @@ -515,6 +528,13 @@ async function loadFromWellKnown(
};
}

/**
* Loads the OIDC provider configuration from environment variables.
*
* @param scopes - Comma-separated scopes to use for OIDC requests
* @returns The parsed OIDC configuration
* @throws If a required OIDC environment variable is missing
*/
function loadFromEnvVars(scopes: string | undefined): OIDCConfiguration {
const authorizationEndpoint = process.env.OIDC_AUTHORIZATION as
string | undefined;
Expand Down Expand Up @@ -557,6 +577,12 @@ function loadFromEnvVars(scopes: string | undefined): OIDCConfiguration {
};
}

/**
* Validates that configured OIDC endpoints use HTTPS.
*
* @param configuration - The OIDC configuration whose endpoint URLs are checked
* @throws If a configured endpoint does not use HTTPS
*/
function validateOIDCEndpointSecurity(configuration: OIDCConfiguration) {
const endpoints: OIDCUrlKey[] = [
"authorization_endpoint",
Expand All @@ -574,6 +600,12 @@ function validateOIDCEndpointSecurity(configuration: OIDCConfiguration) {
}
}

/**
* Determines whether a URL uses HTTPS.
*
* @param url - The URL to inspect
* @returns `true` if the URL uses HTTPS, `false` otherwise.
*/
function isHttps(url: URL | string): boolean {
const parsedUrl = typeof url === "string" ? new URL(url) : url;
if (parsedUrl.protocol === "https:") return true;
Expand Down
8 changes: 4 additions & 4 deletions server/server/internal/auth/passwordHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import * as argon2 from "argon2";
/**
* Verifies a password against a bcrypt hash.
*
* @param password - The plaintext password to verify.
* @param hash - The bcrypt hash to compare against.
* @returns Whether the password matches the hash.
* @param password - The plaintext password to verify
* @param hash - The bcrypt hash to compare against
* @returns `true` if the password matches the hash, `false` otherwise
*/
export async function checkHashBcrypt(password: string, hash: string) {
return await bcrypt.compare(password, hash);
Expand All @@ -27,7 +27,7 @@ export async function createHashArgon2(password: string) {
*
* @param password - The plaintext password to verify.
* @param hash - The Argon2id hash to compare against.
* @returns Whether the password matches the hash.
* @returns `true` if the password matches the hash, `false` otherwise.
*/
export async function checkHashArgon2(password: string, hash: string) {
return await argon2.verify(hash, password);
Expand Down
4 changes: 2 additions & 2 deletions server/server/internal/auth/webauthn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import type { AuthenticatorTransportFuture } from "@simplewebauthn/server";
/**
* Resolves the WebAuthn relying party ID from the configured external URL.
*
* Falls back to `WEBAUTHN_DOMAIN` env var if set, otherwise reads the
* system's external URL config.
* Uses `WEBAUTHN_DOMAIN` when available and otherwise uses the system's external
* URL configuration.
*
* @returns The hostname portion of the relying party URL.
*/
Expand Down
10 changes: 5 additions & 5 deletions server/server/internal/library/manifest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ function buildFileList(
}

/**
* Builds manifests for the files selected from an ordered version chain.
* Builds filtered manifests and aggregates installation and download sizes for files provided by each version.
*
* @param versionOrder - Versions and their droplet manifests, ordered for processing
* @param fileList - Mapping of filenames to the version that provides them
* @param existingChunks - Previously generated manifest details used to exclude existing files
* @returns Filtered manifests and the installation and download sizes
* @param versionOrder - Versions to process in order, including their serialized manifests
* @param fileList - Mapping of each selected filename to the version that provides it
* @param existingChunks - Previously generated manifest details whose files should be excluded
* @returns Filtered manifests with the total installation size and download size
*/
function buildVersionManifests(
versionOrder: Array<{
Expand Down
6 changes: 6 additions & 0 deletions server/server/internal/library/manifest/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ export type V2FileEntry = {
permissions: number;
};

/**
* Parses a serialized manifest into a version 2 manifest.
*
* @param manifest - The serialized manifest value.
* @returns The parsed version 2 manifest.
*/
export function castManifest(manifest: JsonValue): V2Manifest {
return JSON.parse(manifest as string) as V2Manifest;
}
5 changes: 5 additions & 0 deletions server/server/internal/services/services/nginx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { systemConfig } from "../../config/sys-conf";
import path from "node:path";
import fs from "node:fs";

/**
* Resolves the executable path for the Nginx binary.
*
* @returns The first existing known Nginx path, or `"nginx"` when no known path exists.
*/
function resolveNginxPath(): string {
const knownPaths = ["/usr/sbin/nginx", "/usr/local/bin/nginx", "/usr/bin/nginx"];
for (const p of knownPaths) {
Expand Down
16 changes: 6 additions & 10 deletions server/server/internal/services/torrential/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@ import type {
} from "../../proto/torrential/proto/core_pb";

/**
* Defines a query processor for the Torrential service message pipeline.
* Defines a query processor configuration for the Torrential service message pipeline.
*
* Query processors match messages by type and deserialize them into the
* specified protobuf message type. They can optionally return a response
* that is automatically wrapped and sent back.
*
* @typeParam T - The DropBound (outbound) message type enum.
* @typeParam K - The TorrentialBound (inbound) message type enum.
* @typeParam V - The protobuf message class for deserialization.
* @param opts - The processor configuration including type matchers and handler.
* @returns The supplied processor configuration.
* @typeParam T - The outbound message type.
* @typeParam K - The inbound message type.
* @typeParam V - The protobuf message type.
* @param opts - The query processor configuration.
* @returns The supplied query processor configuration.
*/
export function defineQueryProcessor<
T extends DropBoundType,
Expand Down
30 changes: 26 additions & 4 deletions server/server/internal/session/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,11 @@ export default function createDBSessionHandler(): SessionProvider {
}

/**
* Walks a JSON object and returns all paths and their corresponding values.
* @param obj The JSON object to walk.
* @param basePath The base path to start from (used for recursion).
* @returns An array of objects containing the path and value.
* Enumerates paths and their corresponding leaf values within JSON-compatible data.
*
* @param obj - The data to traverse.
* @param basePath - The path prefix for the returned entries.
* @returns The paths and values found beneath the input data.
*/
function walkJsonPath(
obj: unknown,
Expand All @@ -171,6 +172,13 @@ function walkJsonPath(
return [];
}

/**
* Collects paths and values for defined elements in an array.
*
* @param arr - The array to traverse
* @param basePath - The path prefix for each array element
* @returns Path and value pairs for the array's defined elements
*/
function walkArray(
arr: unknown[],
basePath: string[],
Expand All @@ -184,6 +192,13 @@ function walkArray(
return results;
}

/**
* Collects paths and primitive values from an object, excluding undefined properties.
*
* @param obj - The object to traverse
* @param basePath - The path prefix for the object's properties
* @returns The paths and values found within the object
*/
function walkObject(
obj: Record<string, unknown>,
basePath: string[],
Expand All @@ -196,6 +211,13 @@ function walkObject(
return results;
}

/**
* Collects a leaf value and its JSON path, expanding nested objects and arrays.
*
* @param value - The value to collect or expand
* @param path - The path associated with the value
* @param results - The array to which collected path-value pairs are appended
*/
function collectPathValue(
value: unknown,
path: string[],
Expand Down
8 changes: 4 additions & 4 deletions server/server/internal/session/filter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { SessionWithToken, SessionSearchTerms } from "./types";

/**
* Checks if a session matches the given search criteria.
* Determines whether a session satisfies all provided search criteria.
*
* @param session - The session to check
* @param options - The search criteria to match against
* @returns True if the session matches all criteria, false otherwise
* @param session - The session to evaluate
* @param options - The search criteria to apply
* @returns `true` if all specified criteria match the session, `false` otherwise
*/
export function sessionMatchesFilter(
session: SessionWithToken,
Expand Down
5 changes: 5 additions & 0 deletions server/server/internal/session/memory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { SessionProvider, SessionWithToken } from "./types";
import { sessionMatchesFilter } from "./filter";

/**
* Creates an in-memory session provider for storing and managing sessions.
*
* @returns A session provider backed by an in-memory store
*/
export default function createMemorySessionHandler() {
const sessions = new Map<string, SessionWithToken>();

Expand Down
13 changes: 4 additions & 9 deletions server/server/internal/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,16 +449,11 @@ export type TaskRunContext = {
};

/**
* Wraps a task run context, remapping its progress range and attaching
* a child logger with the given prefix.
* Creates a task context with scoped progress reporting and a prefixed child logger.
*
* Useful when a parent task delegates work to a sub-task and needs
* independent progress reporting (e.g. 0-100 maps to min-max range)
* without conflicting with the parent's own progress bar.
*
* @param context - The parent task's run context.
* @param options - Scoping options: min/max progress range and logger prefix.
* @returns A new context that maps progress(0-100) into min-max space.
* @param context - The context whose progress and logger are scoped.
* @param options - Progress range and logger prefix for the child context.
* @returns A context that maps progress from 0–100 to the specified range.
*/
export function wrapTaskContext(
context: TaskRunContext,
Expand Down
7 changes: 7 additions & 0 deletions server/server/internal/utils/recursivedirs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import fs from "node:fs";
import path from "node:path";

/**
* Collects file paths under a directory, traversing nested directories up to the specified depth.
*
* @param dir - The directory whose files should be collected
* @param depth - The maximum number of directory levels to traverse
* @returns The paths of files found under the directory
*/
export function recursivelyReaddir(dir: string, depth: number = 100) {
if (depth == 0) return [];
const result: Array<string> = [];
Expand Down
3 changes: 3 additions & 0 deletions sites/promo/src/components/linked-avatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const transition = {
repeatDelay: 1.25,
};

/**
* Renders concentric animated rings as an SVG background.
*/
function Rings() {
return (
<svg
Expand Down
8 changes: 4 additions & 4 deletions sites/promo/src/components/screenshot.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { clsx } from "clsx";

/**
* Renders an image in a styled frame with a fixed aspect ratio and screenshot disclaimer.
* Renders an image in a styled frame with a fixed aspect ratio and disclaimer.
*
* @param width - The image width used to determine the frame's aspect ratio
* @param height - The image height used to determine the frame's aspect ratio
* @param width - The width used to determine the frame's aspect ratio
* @param height - The height used to determine the frame's aspect ratio
* @param src - The image source
* @param className - Additional classes applied to the frame
* @returns The rendered screenshot frame
* @returns The rendered frame containing the screenshot and disclaimer
*/
export function Screenshot({
width,
Expand Down