mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-16 21:33:41 +00:00
refactor(tests): move backend tests into src/backend/tests mirror tree
Backend *.test.ts files (and the test-support harness) no longer sit next to source files; they live under src/backend/tests/ mirroring the source layout. Imports rewritten accordingly; CLAUDE.md convention updated.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { AlertRepository } from "./alert-repository.js";
|
import { AlertRepository } from "../../../database/repositories/alert-repository.js";
|
||||||
|
|
||||||
describe("AlertRepository", () => {
|
describe("AlertRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { ApiKeyRepository } from "./api-key-repository.js";
|
import { ApiKeyRepository } from "../../../database/repositories/api-key-repository.js";
|
||||||
|
|
||||||
describe("ApiKeyRepository", () => {
|
describe("ApiKeyRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { AuditLogRepository } from "./audit-log-repository.js";
|
import { AuditLogRepository } from "../../../database/repositories/audit-log-repository.js";
|
||||||
|
|
||||||
describe("AuditLogRepository", () => {
|
describe("AuditLogRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { C2sTunnelPresetRepository } from "./c2s-tunnel-preset-repository.js";
|
import { C2sTunnelPresetRepository } from "../../../database/repositories/c2s-tunnel-preset-repository.js";
|
||||||
|
|
||||||
describe("C2sTunnelPresetRepository", () => {
|
describe("C2sTunnelPresetRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { CommandHistoryRepository } from "./command-history-repository.js";
|
import { CommandHistoryRepository } from "../../../database/repositories/command-history-repository.js";
|
||||||
|
|
||||||
describe("CommandHistoryRepository", () => {
|
describe("CommandHistoryRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { DashboardServiceLinkRepository } from "./dashboard-service-link-repository.js";
|
import { DashboardServiceLinkRepository } from "../../../database/repositories/dashboard-service-link-repository.js";
|
||||||
|
|
||||||
describe("DashboardServiceLinkRepository", () => {
|
describe("DashboardServiceLinkRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { DismissedAlertRepository } from "./dismissed-alert-repository.js";
|
import { DismissedAlertRepository } from "../../../database/repositories/dismissed-alert-repository.js";
|
||||||
|
|
||||||
describe("DismissedAlertRepository", () => {
|
describe("DismissedAlertRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { FieldEncryptionBoundary } from "./field-encryption-boundary.js";
|
import { FieldEncryptionBoundary } from "../../../database/repositories/field-encryption-boundary.js";
|
||||||
|
|
||||||
describe("FieldEncryptionBoundary", () => {
|
describe("FieldEncryptionBoundary", () => {
|
||||||
const userDataKey = crypto.randomBytes(32);
|
const userDataKey = crypto.randomBytes(32);
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { FileManagerBookmarkRepository } from "./file-manager-bookmark-repository.js";
|
import { FileManagerBookmarkRepository } from "../../../database/repositories/file-manager-bookmark-repository.js";
|
||||||
|
|
||||||
describe("FileManagerBookmarkRepository", () => {
|
describe("FileManagerBookmarkRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { HomepageItemRepository } from "./homepage-item-repository.js";
|
import { HomepageItemRepository } from "../../../database/repositories/homepage-item-repository.js";
|
||||||
|
|
||||||
describe("HomepageItemRepository", () => {
|
describe("HomepageItemRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { HomepageLayoutRepository } from "./homepage-layout-repository.js";
|
import { HomepageLayoutRepository } from "../../../database/repositories/homepage-layout-repository.js";
|
||||||
|
|
||||||
describe("HomepageLayoutRepository", () => {
|
describe("HomepageLayoutRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { CredentialRepository } from "./credential-repository.js";
|
import { CredentialRepository } from "../../../database/repositories/credential-repository.js";
|
||||||
import { HostRepository } from "./host-repository.js";
|
import { HostRepository } from "../../../database/repositories/host-repository.js";
|
||||||
import { DataCrypto } from "../../utils/data-crypto.js";
|
import { DataCrypto } from "../../../utils/data-crypto.js";
|
||||||
|
|
||||||
describe("HostRepository and CredentialRepository", () => {
|
describe("HostRepository and CredentialRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { HostFolderRepository } from "./host-folder-repository.js";
|
import { HostFolderRepository } from "../../../database/repositories/host-folder-repository.js";
|
||||||
|
|
||||||
describe("HostFolderRepository", () => {
|
describe("HostFolderRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { HostHealthRepository } from "./host-health-repository.js";
|
import { HostHealthRepository } from "../../../database/repositories/host-health-repository.js";
|
||||||
|
|
||||||
describe("HostHealthRepository", () => {
|
describe("HostHealthRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { HostMetricsHistoryRepository } from "./host-metrics-history-repository.js";
|
import { HostMetricsHistoryRepository } from "../../../database/repositories/host-metrics-history-repository.js";
|
||||||
|
|
||||||
describe("HostMetricsHistoryRepository", () => {
|
describe("HostMetricsHistoryRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { HostMetricsPreferenceRepository } from "./host-metrics-preference-repository.js";
|
import { HostMetricsPreferenceRepository } from "../../../database/repositories/host-metrics-preference-repository.js";
|
||||||
|
|
||||||
describe("HostMetricsPreferenceRepository", () => {
|
describe("HostMetricsPreferenceRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { DataCrypto } from "../../utils/data-crypto.js";
|
import { DataCrypto } from "../../../utils/data-crypto.js";
|
||||||
import { HostResolutionRepository } from "./host-resolution-repository.js";
|
import { HostResolutionRepository } from "../../../database/repositories/host-resolution-repository.js";
|
||||||
|
|
||||||
vi.mock("../../utils/data-crypto.js", () => ({
|
vi.mock("../../../utils/data-crypto.js", () => ({
|
||||||
DataCrypto: {
|
DataCrypto: {
|
||||||
getUserDataKey: vi.fn(),
|
getUserDataKey: vi.fn(),
|
||||||
decryptRecord: vi.fn((_tableName, record) => record),
|
decryptRecord: vi.fn((_tableName, record) => record),
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { NetworkTopologyRepository } from "./network-topology-repository.js";
|
import { NetworkTopologyRepository } from "../../../database/repositories/network-topology-repository.js";
|
||||||
|
|
||||||
describe("NetworkTopologyRepository", () => {
|
describe("NetworkTopologyRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { OpenTabRepository } from "./open-tab-repository.js";
|
import { OpenTabRepository } from "../../../database/repositories/open-tab-repository.js";
|
||||||
|
|
||||||
describe("OpenTabRepository", () => {
|
describe("OpenTabRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { OpksshTokenRepository } from "./opkssh-token-repository.js";
|
import { OpksshTokenRepository } from "../../../database/repositories/opkssh-token-repository.js";
|
||||||
|
|
||||||
describe("OpksshTokenRepository", () => {
|
describe("OpksshTokenRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { RbacAccessRepository } from "./rbac-access-repository.js";
|
import { RbacAccessRepository } from "../../../database/repositories/rbac-access-repository.js";
|
||||||
|
|
||||||
describe("RbacAccessRepository", () => {
|
describe("RbacAccessRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { RecentActivityRepository } from "./recent-activity-repository.js";
|
import { RecentActivityRepository } from "../../../database/repositories/recent-activity-repository.js";
|
||||||
|
|
||||||
describe("RecentActivityRepository", () => {
|
describe("RecentActivityRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { RoleRepository } from "./role-repository.js";
|
import { RoleRepository } from "../../../database/repositories/role-repository.js";
|
||||||
|
|
||||||
describe("RoleRepository", () => {
|
describe("RoleRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SessionRecordingRepository } from "./session-recording-repository.js";
|
import { SessionRecordingRepository } from "../../../database/repositories/session-recording-repository.js";
|
||||||
|
|
||||||
describe("SessionRecordingRepository", () => {
|
describe("SessionRecordingRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SettingsRepository } from "./settings-repository.js";
|
import { SettingsRepository } from "../../../database/repositories/settings-repository.js";
|
||||||
|
|
||||||
describe("SettingsRepository", () => {
|
describe("SettingsRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SharedCredentialRepository } from "./shared-credential-repository.js";
|
import { SharedCredentialRepository } from "../../../database/repositories/shared-credential-repository.js";
|
||||||
|
|
||||||
describe("SharedCredentialRepository", () => {
|
describe("SharedCredentialRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SnippetRepository } from "./snippet-repository.js";
|
import { SnippetRepository } from "../../../database/repositories/snippet-repository.js";
|
||||||
|
|
||||||
describe("SnippetRepository", () => {
|
describe("SnippetRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SshCredentialUsageRepository } from "./ssh-credential-usage-repository.js";
|
import { SshCredentialUsageRepository } from "../../../database/repositories/ssh-credential-usage-repository.js";
|
||||||
|
|
||||||
describe("SshCredentialUsageRepository", () => {
|
describe("SshCredentialUsageRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SsoProviderRepository } from "./sso-provider-repository.js";
|
import { SsoProviderRepository } from "../../../database/repositories/sso-provider-repository.js";
|
||||||
|
|
||||||
describe("SsoProviderRepository", () => {
|
describe("SsoProviderRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { DataCrypto } from "../../utils/data-crypto.js";
|
import { DataCrypto } from "../../../utils/data-crypto.js";
|
||||||
import { TermixIdentityCaRepository } from "./termix-identity-ca-repository.js";
|
import { TermixIdentityCaRepository } from "../../../database/repositories/termix-identity-ca-repository.js";
|
||||||
|
|
||||||
describe("TermixIdentityCaRepository", () => {
|
describe("TermixIdentityCaRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { TermixIdentityRepository } from "./termix-identity-repository.js";
|
import { TermixIdentityRepository } from "../../../database/repositories/termix-identity-repository.js";
|
||||||
|
|
||||||
describe("TermixIdentityRepository", () => {
|
describe("TermixIdentityRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
import Database from "better-sqlite3";
|
import Database from "better-sqlite3";
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||||
import * as schema from "../db/schema.js";
|
import * as schema from "../../../database/db/schema.js";
|
||||||
import type { DatabaseContext } from "./database-context.js";
|
import type { DatabaseContext } from "../../../database/repositories/database-context.js";
|
||||||
|
|
||||||
export class TestSqliteDatabase {
|
export class TestSqliteDatabase {
|
||||||
private sqlite: Database.Database | null = null;
|
private sqlite: Database.Database | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { TmuxSessionTagRepository } from "./tmux-session-tag-repository.js";
|
import { TmuxSessionTagRepository } from "../../../database/repositories/tmux-session-tag-repository.js";
|
||||||
|
|
||||||
describe("TmuxSessionTagRepository", () => {
|
describe("TmuxSessionTagRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { TransferRecentRepository } from "./transfer-recent-repository.js";
|
import { TransferRecentRepository } from "../../../database/repositories/transfer-recent-repository.js";
|
||||||
|
|
||||||
describe("TransferRecentRepository", () => {
|
describe("TransferRecentRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { TrustedDeviceRepository } from "./trusted-device-repository.js";
|
import { TrustedDeviceRepository } from "../../../database/repositories/trusted-device-repository.js";
|
||||||
|
|
||||||
describe("TrustedDeviceRepository", () => {
|
describe("TrustedDeviceRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { UserDataExportRepository } from "./user-data-export-repository.js";
|
import { UserDataExportRepository } from "../../../database/repositories/user-data-export-repository.js";
|
||||||
|
|
||||||
describe("UserDataExportRepository", () => {
|
describe("UserDataExportRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { UserPreferenceRepository } from "./user-preference-repository.js";
|
import { UserPreferenceRepository } from "../../../database/repositories/user-preference-repository.js";
|
||||||
|
|
||||||
describe("UserPreferenceRepository", () => {
|
describe("UserPreferenceRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { SessionRepository } from "./session-repository.js";
|
import { SessionRepository } from "../../../database/repositories/session-repository.js";
|
||||||
import { UserRepository } from "./user-repository.js";
|
import { UserRepository } from "../../../database/repositories/user-repository.js";
|
||||||
|
|
||||||
describe("UserRepository and SessionRepository", () => {
|
describe("UserRepository and SessionRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { VaultProfileRepository } from "./vault-profile-repository.js";
|
import { VaultProfileRepository } from "../../../database/repositories/vault-profile-repository.js";
|
||||||
|
|
||||||
describe("VaultProfileRepository", () => {
|
describe("VaultProfileRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { TestSqliteDatabase } from "./test-support.js";
|
import { TestSqliteDatabase } from "./test-support.js";
|
||||||
import { VaultTokenRepository } from "./vault-token-repository.js";
|
import { VaultTokenRepository } from "../../../database/repositories/vault-token-repository.js";
|
||||||
|
|
||||||
describe("VaultTokenRepository", () => {
|
describe("VaultTokenRepository", () => {
|
||||||
let adapter: TestSqliteDatabase | null = null;
|
let adapter: TestSqliteDatabase | null = null;
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { parseSSHConfig } from "./host-bulk-routes.js";
|
import { parseSSHConfig } from "../../../database/routes/host-bulk-routes.js";
|
||||||
|
|
||||||
describe("parseSSHConfig", () => {
|
describe("parseSSHConfig", () => {
|
||||||
it("parses a basic Host block", () => {
|
it("parses a basic Host block", () => {
|
||||||
+2
-2
@@ -4,14 +4,14 @@ const mocks = vi.hoisted(() => ({
|
|||||||
isUserDataUnlocked: vi.fn(),
|
isUserDataUnlocked: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/simple-db-ops.js", () => ({
|
vi.mock("../../../utils/simple-db-ops.js", () => ({
|
||||||
SimpleDBOps: {
|
SimpleDBOps: {
|
||||||
isUserDataUnlocked: mocks.isUserDataUnlocked,
|
isUserDataUnlocked: mocks.isUserDataUnlocked,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { applyHostEnrollmentDefaults, requireHostEnrollmentAccessForPath } =
|
const { applyHostEnrollmentDefaults, requireHostEnrollmentAccessForPath } =
|
||||||
await import("./host-enrollment-auth.js");
|
await import("../../../database/routes/host-enrollment-auth.js");
|
||||||
|
|
||||||
function response() {
|
function response() {
|
||||||
const json = vi.fn();
|
const json = vi.fn();
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
|||||||
renameFolderPath,
|
renameFolderPath,
|
||||||
stripSensitiveFields,
|
stripSensitiveFields,
|
||||||
transformHostResponse,
|
transformHostResponse,
|
||||||
} from "./host-normalizers.js";
|
} from "../../../database/routes/host-normalizers.js";
|
||||||
|
|
||||||
describe("isNonEmptyString", () => {
|
describe("isNonEmptyString", () => {
|
||||||
it("accepts non-blank strings", () => {
|
it("accepts non-blank strings", () => {
|
||||||
+1
-1
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
import {
|
import {
|
||||||
isValidServiceLinkUrl,
|
isValidServiceLinkUrl,
|
||||||
normalizeServiceLinkUrl,
|
normalizeServiceLinkUrl,
|
||||||
} from "./service-link-url.js";
|
} from "../../../database/routes/service-link-url.js";
|
||||||
|
|
||||||
describe("service link URL handling", () => {
|
describe("service link URL handling", () => {
|
||||||
it("keeps explicit http and https URLs", () => {
|
it("keeps explicit http and https URLs", () => {
|
||||||
+5
-4
@@ -6,7 +6,7 @@ const mockSelect = vi.fn();
|
|||||||
const mockDelete = vi.fn();
|
const mockDelete = vi.fn();
|
||||||
const mockInsert = vi.fn();
|
const mockInsert = vi.fn();
|
||||||
|
|
||||||
vi.mock("../db/index.js", () => ({
|
vi.mock("../../../database/db/index.js", () => ({
|
||||||
db: {
|
db: {
|
||||||
select: mockSelect,
|
select: mockSelect,
|
||||||
delete: mockDelete,
|
delete: mockDelete,
|
||||||
@@ -14,11 +14,11 @@ vi.mock("../db/index.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/logger.js", () => ({
|
vi.mock("../../../utils/logger.js", () => ({
|
||||||
apiLogger: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), success: vi.fn() },
|
apiLogger: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), success: vi.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/auth-manager.js", () => ({
|
vi.mock("../../../utils/auth-manager.js", () => ({
|
||||||
AuthManager: {
|
AuthManager: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
createAuthMiddleware:
|
createAuthMiddleware:
|
||||||
@@ -92,7 +92,8 @@ describe("session-log-routes", () => {
|
|||||||
mockStat.mockReturnValue({ size: 4096 });
|
mockStat.mockReturnValue({ size: 4096 });
|
||||||
|
|
||||||
// Directly call the route handler extracted from the module
|
// Directly call the route handler extracted from the module
|
||||||
const { default: router } = await import("./session-log-routes.js");
|
const { default: router } =
|
||||||
|
await import("../../../database/routes/session-log-routes.js");
|
||||||
expect(router).toBeDefined();
|
expect(router).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
+1
-1
@@ -8,7 +8,7 @@ import {
|
|||||||
generateCa,
|
generateCa,
|
||||||
signUserCertificate,
|
signUserCertificate,
|
||||||
ed25519RawFromLine,
|
ed25519RawFromLine,
|
||||||
} from "./ssh-certificate.js";
|
} from "../../../database/routes/ssh-certificate.js";
|
||||||
|
|
||||||
function publicKeyObjectFromLine(line: string) {
|
function publicKeyObjectFromLine(line: string) {
|
||||||
const raw = ed25519RawFromLine(line);
|
const raw = ed25519RawFromLine(line);
|
||||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
|||||||
parsePublicKey,
|
parsePublicKey,
|
||||||
matchesAlgoFilter,
|
matchesAlgoFilter,
|
||||||
MAX_PUBLIC_KEY_LENGTH,
|
MAX_PUBLIC_KEY_LENGTH,
|
||||||
} from "./termix-id-keys.js";
|
} from "../../../database/routes/termix-id-keys.js";
|
||||||
|
|
||||||
// Build a valid OpenSSH public-key line for a given type by encoding a wire
|
// Build a valid OpenSSH public-key line for a given type by encoding a wire
|
||||||
// blob whose first string field equals the type (what parsePublicKey checks).
|
// blob whose first string field equals the type (what parsePublicKey checks).
|
||||||
+15
-11
@@ -5,7 +5,7 @@ const mockUpdate = vi.fn();
|
|||||||
const mockInsert = vi.fn();
|
const mockInsert = vi.fn();
|
||||||
const mockDelete = vi.fn();
|
const mockDelete = vi.fn();
|
||||||
|
|
||||||
vi.mock("../db/index.js", () => ({
|
vi.mock("../../../database/db/index.js", () => ({
|
||||||
db: {
|
db: {
|
||||||
select: mockSelect,
|
select: mockSelect,
|
||||||
update: mockUpdate,
|
update: mockUpdate,
|
||||||
@@ -14,7 +14,7 @@ vi.mock("../db/index.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/logger.js", () => ({
|
vi.mock("../../../utils/logger.js", () => ({
|
||||||
apiLogger: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), success: vi.fn() },
|
apiLogger: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), success: vi.fn() },
|
||||||
authLogger: {
|
authLogger: {
|
||||||
error: vi.fn(),
|
error: vi.fn(),
|
||||||
@@ -24,7 +24,7 @@ vi.mock("../../utils/logger.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/auth-manager.js", () => ({
|
vi.mock("../../../utils/auth-manager.js", () => ({
|
||||||
AuthManager: {
|
AuthManager: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
createAuthMiddleware:
|
createAuthMiddleware:
|
||||||
@@ -40,16 +40,16 @@ vi.mock("../../utils/auth-manager.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/audit-logger.js", () => ({
|
vi.mock("../../../utils/audit-logger.js", () => ({
|
||||||
logAudit: vi.fn(),
|
logAudit: vi.fn(),
|
||||||
getRequestMeta: vi.fn(() => ({})),
|
getRequestMeta: vi.fn(() => ({})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/data-crypto.js", () => ({
|
vi.mock("../../../utils/data-crypto.js", () => ({
|
||||||
DataCrypto: { getInstance: () => ({ encrypt: vi.fn(), decrypt: vi.fn() }) },
|
DataCrypto: { getInstance: () => ({ encrypt: vi.fn(), decrypt: vi.fn() }) },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../repositories/factory.js", () => ({
|
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||||
createCurrentTermixIdentityCaRepository: vi.fn(() => ({
|
createCurrentTermixIdentityCaRepository: vi.fn(() => ({
|
||||||
findPublicByIdentityId: vi.fn(),
|
findPublicByIdentityId: vi.fn(),
|
||||||
findDecryptedByIdentityId: vi.fn(),
|
findDecryptedByIdentityId: vi.fn(),
|
||||||
@@ -74,7 +74,7 @@ vi.mock("../repositories/factory.js", () => ({
|
|||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./termix-id-keys.js", () => ({
|
vi.mock("../../../database/routes/termix-id-keys.js", () => ({
|
||||||
termixIdKeysRouter: { use: vi.fn() },
|
termixIdKeysRouter: { use: vi.fn() },
|
||||||
matchesAlgoFilter: vi.fn(() => true),
|
matchesAlgoFilter: vi.fn(() => true),
|
||||||
}));
|
}));
|
||||||
@@ -117,7 +117,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
|||||||
// First select (getIdentityForUser) returns nothing; second should not be called
|
// First select (getIdentityForUser) returns nothing; second should not be called
|
||||||
mockSelect.mockReturnValueOnce(makeChain([]));
|
mockSelect.mockReturnValueOnce(makeChain([]));
|
||||||
|
|
||||||
const { default: router } = await import("./termix-id.js");
|
const { default: router } =
|
||||||
|
await import("../../../database/routes/termix-id.js");
|
||||||
expect(router).toBeDefined();
|
expect(router).toBeDefined();
|
||||||
|
|
||||||
expect(router).toBeDefined();
|
expect(router).toBeDefined();
|
||||||
@@ -128,7 +129,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
|||||||
.mockReturnValueOnce(makeChain([IDENTITY_ROW])) // identity lookup
|
.mockReturnValueOnce(makeChain([IDENTITY_ROW])) // identity lookup
|
||||||
.mockReturnValueOnce(makeChain([])); // keys lookup
|
.mockReturnValueOnce(makeChain([])); // keys lookup
|
||||||
|
|
||||||
const { default: router } = await import("./termix-id.js");
|
const { default: router } =
|
||||||
|
await import("../../../database/routes/termix-id.js");
|
||||||
expect(router).toBeDefined();
|
expect(router).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -142,7 +144,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
|||||||
.mockReturnValueOnce(makeChain([IDENTITY_ROW]))
|
.mockReturnValueOnce(makeChain([IDENTITY_ROW]))
|
||||||
.mockReturnValueOnce(makeChain(keys));
|
.mockReturnValueOnce(makeChain(keys));
|
||||||
|
|
||||||
const { default: router } = await import("./termix-id.js");
|
const { default: router } =
|
||||||
|
await import("../../../database/routes/termix-id.js");
|
||||||
expect(router).toBeDefined();
|
expect(router).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -152,7 +155,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
|||||||
.mockReturnValueOnce(makeChain([IDENTITY_ROW]))
|
.mockReturnValueOnce(makeChain([IDENTITY_ROW]))
|
||||||
.mockReturnValueOnce(makeChain(keys));
|
.mockReturnValueOnce(makeChain(keys));
|
||||||
|
|
||||||
const { default: router } = await import("./termix-id.js");
|
const { default: router } =
|
||||||
|
await import("../../../database/routes/termix-id.js");
|
||||||
expect(router).toBeDefined();
|
expect(router).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||||
|
|
||||||
// user-oidc-utils imports the logger; stub it so importing stays side-effect-free.
|
// user-oidc-utils imports the logger; stub it so importing stays side-effect-free.
|
||||||
vi.mock("../../utils/logger.js", () => ({
|
vi.mock("../../../utils/logger.js", () => ({
|
||||||
authLogger: {
|
authLogger: {
|
||||||
debug: vi.fn(),
|
debug: vi.fn(),
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
@@ -16,7 +16,7 @@ const {
|
|||||||
getOIDCConfigFromEnv,
|
getOIDCConfigFromEnv,
|
||||||
extractOidcGroups,
|
extractOidcGroups,
|
||||||
validateLogoutTokenClaims,
|
validateLogoutTokenClaims,
|
||||||
} = await import("./user-oidc-utils.js");
|
} = await import("../../../database/routes/user-oidc-utils.js");
|
||||||
|
|
||||||
const BACKCHANNEL_LOGOUT_EVENT =
|
const BACKCHANNEL_LOGOUT_EVENT =
|
||||||
"http://schemas.openid.net/event/backchannel-logout";
|
"http://schemas.openid.net/event/backchannel-logout";
|
||||||
+5
-5
@@ -1,5 +1,5 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import type { AuthManager } from "../../utils/auth-manager.js";
|
import type { AuthManager } from "../../../utils/auth-manager.js";
|
||||||
|
|
||||||
const calls = vi.hoisted(() => ({
|
const calls = vi.hoisted(() => ({
|
||||||
userUpdates: [] as Array<[string, Record<string, unknown>]>,
|
userUpdates: [] as Array<[string, Record<string, unknown>]>,
|
||||||
@@ -17,7 +17,7 @@ function deletingRepo(label: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
vi.mock("../repositories/factory.js", () => ({
|
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||||
createCurrentUserRepository: () => ({
|
createCurrentUserRepository: () => ({
|
||||||
update: async (userId: string, update: Record<string, unknown>) => {
|
update: async (userId: string, update: Record<string, unknown>) => {
|
||||||
calls.userUpdates.push([userId, update]);
|
calls.userUpdates.push([userId, update]);
|
||||||
@@ -34,7 +34,7 @@ vi.mock("../repositories/factory.js", () => ({
|
|||||||
createCurrentCredentialRepository: deletingRepo("credentials"),
|
createCurrentCredentialRepository: deletingRepo("credentials"),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/user-keys.js", () => ({
|
vi.mock("../../../utils/user-keys.js", () => ({
|
||||||
UserKeyManager: {
|
UserKeyManager: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
rotateUserDEK: async (userId: string) => {
|
rotateUserDEK: async (userId: string) => {
|
||||||
@@ -45,13 +45,13 @@ vi.mock("../../utils/user-keys.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/crypto-migration/dek-migration.js", () => ({
|
vi.mock("../../../utils/crypto-migration/dek-migration.js", () => ({
|
||||||
deleteLegacyWraps: async (userId: string) => {
|
deleteLegacyWraps: async (userId: string) => {
|
||||||
calls.legacyWrapsDeletedFor.push(userId);
|
calls.legacyWrapsDeletedFor.push(userId);
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { resetUserPassword } from "./user-password-reset-routes.js";
|
import { resetUserPassword } from "../../../database/routes/user-password-reset-routes.js";
|
||||||
|
|
||||||
function fakeAuthManager(unlocked: boolean): AuthManager {
|
function fakeAuthManager(unlocked: boolean): AuthManager {
|
||||||
return {
|
return {
|
||||||
+4
-3
@@ -6,13 +6,13 @@ import speakeasy from "speakeasy";
|
|||||||
// importing stays inert.
|
// importing stays inert.
|
||||||
const userRepositoryUpdate = vi.fn().mockResolvedValue(null);
|
const userRepositoryUpdate = vi.fn().mockResolvedValue(null);
|
||||||
|
|
||||||
vi.mock("../repositories/factory.js", () => ({
|
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||||
createCurrentUserRepository: () => ({
|
createCurrentUserRepository: () => ({
|
||||||
update: userRepositoryUpdate,
|
update: userRepositoryUpdate,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../../utils/logger.js", () => ({
|
vi.mock("../../../utils/logger.js", () => ({
|
||||||
authLogger: {
|
authLogger: {
|
||||||
debug: vi.fn(),
|
debug: vi.fn(),
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
@@ -22,7 +22,8 @@ vi.mock("../../utils/logger.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { verifyTotpReauth } = await import("./user-totp-routes.js");
|
const { verifyTotpReauth } =
|
||||||
|
await import("../../../database/routes/user-totp-routes.js");
|
||||||
|
|
||||||
type AnyUser = Parameters<typeof verifyTotpReauth>[0];
|
type AnyUser = Parameters<typeof verifyTotpReauth>[0];
|
||||||
|
|
||||||
+7
-7
@@ -3,7 +3,7 @@ import {
|
|||||||
pickResolvedUsername,
|
pickResolvedUsername,
|
||||||
pickResolvedPassword,
|
pickResolvedPassword,
|
||||||
expandOidcUsername,
|
expandOidcUsername,
|
||||||
} from "./credential-username.js";
|
} from "../../hosts/credential-username.js";
|
||||||
|
|
||||||
describe("pickResolvedUsername", () => {
|
describe("pickResolvedUsername", () => {
|
||||||
it("keeps the host username when one is set, even with a credential username", () => {
|
it("keeps the host username when one is set, even with a credential username", () => {
|
||||||
@@ -63,40 +63,40 @@ describe("expandOidcUsername", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("expands the placeholder with the user's OIDC identifier", async () => {
|
it("expands the placeholder with the user's OIDC identifier", async () => {
|
||||||
vi.doMock("../database/repositories/factory.js", () => ({
|
vi.doMock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentUserRepository: () => ({
|
createCurrentUserRepository: () => ({
|
||||||
findById: async () => ({ oidcIdentifier: "jdoe" }),
|
findById: async () => ({ oidcIdentifier: "jdoe" }),
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { expandOidcUsername: expand } =
|
const { expandOidcUsername: expand } =
|
||||||
await import("./credential-username.js");
|
await import("../../hosts/credential-username.js");
|
||||||
expect(await expand("$oidc.preferred_username", "user-1")).toBe("jdoe");
|
expect(await expand("$oidc.preferred_username", "user-1")).toBe("jdoe");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("leaves the placeholder as-is when the user has no OIDC identifier", async () => {
|
it("leaves the placeholder as-is when the user has no OIDC identifier", async () => {
|
||||||
vi.doMock("../database/repositories/factory.js", () => ({
|
vi.doMock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentUserRepository: () => ({
|
createCurrentUserRepository: () => ({
|
||||||
findById: async () => ({ oidcIdentifier: null }),
|
findById: async () => ({ oidcIdentifier: null }),
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { expandOidcUsername: expand } =
|
const { expandOidcUsername: expand } =
|
||||||
await import("./credential-username.js");
|
await import("../../hosts/credential-username.js");
|
||||||
expect(await expand("$oidc.preferred_username", "user-1")).toBe(
|
expect(await expand("$oidc.preferred_username", "user-1")).toBe(
|
||||||
"$oidc.preferred_username",
|
"$oidc.preferred_username",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns the username unchanged when the DB lookup throws", async () => {
|
it("returns the username unchanged when the DB lookup throws", async () => {
|
||||||
vi.doMock("../database/repositories/factory.js", () => ({
|
vi.doMock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentUserRepository: () => {
|
createCurrentUserRepository: () => {
|
||||||
throw new Error("DB unavailable");
|
throw new Error("DB unavailable");
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { expandOidcUsername: expand } =
|
const { expandOidcUsername: expand } =
|
||||||
await import("./credential-username.js");
|
await import("../../hosts/credential-username.js");
|
||||||
expect(await expand("$oidc.preferred_username", "user-1")).toBe(
|
expect(await expand("$oidc.preferred_username", "user-1")).toBe(
|
||||||
"$oidc.preferred_username",
|
"$oidc.preferred_username",
|
||||||
);
|
);
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import { buildDeleteCommand } from "./file-manager-operation-commands.js";
|
import { buildDeleteCommand } from "../../hosts/file-manager-operation-commands.js";
|
||||||
|
|
||||||
describe("buildDeleteCommand", () => {
|
describe("buildDeleteCommand", () => {
|
||||||
it("builds a PowerShell 5.1 compatible delete command for Windows files", () => {
|
it("builds a PowerShell 5.1 compatible delete command for Windows files", () => {
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
|||||||
getMimeType,
|
getMimeType,
|
||||||
detectBinary,
|
detectBinary,
|
||||||
parseLsDateToTimestamp,
|
parseLsDateToTimestamp,
|
||||||
} from "./file-manager-utils.js";
|
} from "../../hosts/file-manager-utils.js";
|
||||||
|
|
||||||
describe("isExecutableFile", () => {
|
describe("isExecutableFile", () => {
|
||||||
it("flags scripts with execute permission", () => {
|
it("flags scripts with execute permission", () => {
|
||||||
+3
-2
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
vi.mock("../../utils/logger.js", () => ({
|
vi.mock("../../../utils/logger.js", () => ({
|
||||||
guacLogger: {
|
guacLogger: {
|
||||||
debug: vi.fn(),
|
debug: vi.fn(),
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
@@ -10,7 +10,8 @@ vi.mock("../../utils/logger.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { GuacamoleTokenService } = await import("./token-service.js");
|
const { GuacamoleTokenService } =
|
||||||
|
await import("../../../hosts/guacamole/token-service.js");
|
||||||
|
|
||||||
describe("GuacamoleTokenService", () => {
|
describe("GuacamoleTokenService", () => {
|
||||||
const tokenService = GuacamoleTokenService.getInstance();
|
const tokenService = GuacamoleTokenService.getInstance();
|
||||||
+2
-2
@@ -4,8 +4,8 @@ import {
|
|||||||
supportsMetrics,
|
supportsMetrics,
|
||||||
isTcpPingEnabled,
|
isTcpPingEnabled,
|
||||||
tcpPingThroughJumpHost,
|
tcpPingThroughJumpHost,
|
||||||
} from "./host-metrics-helpers.js";
|
} from "../../hosts/host-metrics-helpers.js";
|
||||||
import { createConnectionLog } from "./connection-log.js";
|
import { createConnectionLog } from "../../hosts/connection-log.js";
|
||||||
|
|
||||||
describe("supportsMetrics", () => {
|
describe("supportsMetrics", () => {
|
||||||
it("supports plain ssh hosts", () => {
|
it("supports plain ssh hosts", () => {
|
||||||
+1
-1
@@ -5,7 +5,7 @@ import {
|
|||||||
isMetricCardId,
|
isMetricCardId,
|
||||||
isManagerCardId,
|
isManagerCardId,
|
||||||
METRIC_CARD_IDS,
|
METRIC_CARD_IDS,
|
||||||
} from "../../types/host-metrics.js";
|
} from "../../../types/host-metrics.js";
|
||||||
|
|
||||||
describe("deriveEnabledWidgets", () => {
|
describe("deriveEnabledWidgets", () => {
|
||||||
it("returns only metric ids, in canonical order, deduped", () => {
|
it("returns only metric ids, in canonical order, deduped", () => {
|
||||||
+4
-1
@@ -1,5 +1,8 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { ConcurrentLimiter, HostPollCache } from "./host-metrics-state.js";
|
import {
|
||||||
|
ConcurrentLimiter,
|
||||||
|
HostPollCache,
|
||||||
|
} from "../../hosts/host-metrics-state.js";
|
||||||
|
|
||||||
describe("ConcurrentLimiter", () => {
|
describe("ConcurrentLimiter", () => {
|
||||||
it("never exceeds max concurrent runners", async () => {
|
it("never exceeds max concurrent runners", async () => {
|
||||||
+5
-2
@@ -1,11 +1,14 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||||
|
|
||||||
const execCommand = vi.fn();
|
const execCommand = vi.fn();
|
||||||
vi.mock("../widgets/common-utils.js", () => ({
|
vi.mock("../../../hosts/widgets/common-utils.js", () => ({
|
||||||
execCommand: (...args: unknown[]) => execCommand(...args),
|
execCommand: (...args: unknown[]) => execCommand(...args),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { execElevated, ElevationError } from "./exec-elevated.js";
|
import {
|
||||||
|
execElevated,
|
||||||
|
ElevationError,
|
||||||
|
} from "../../../hosts/managers/exec-elevated.js";
|
||||||
import type { Client } from "ssh2";
|
import type { Client } from "ssh2";
|
||||||
|
|
||||||
const fakeClient = {} as Client;
|
const fakeClient = {} as Client;
|
||||||
+31
-13
@@ -1,6 +1,9 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { buildSudoCommand, shellSingleQuote } from "./exec-elevated.js";
|
import {
|
||||||
import { parsePlatformProbe } from "./platform.js";
|
buildSudoCommand,
|
||||||
|
shellSingleQuote,
|
||||||
|
} from "../../../hosts/managers/exec-elevated.js";
|
||||||
|
import { parsePlatformProbe } from "../../../hosts/managers/platform.js";
|
||||||
import {
|
import {
|
||||||
isValidSystemdUnit,
|
isValidSystemdUnit,
|
||||||
isValidPid,
|
isValidPid,
|
||||||
@@ -12,32 +15,47 @@ import {
|
|||||||
isValidSignal,
|
isValidSignal,
|
||||||
isValidServiceAction,
|
isValidServiceAction,
|
||||||
isAllowedPath,
|
isAllowedPath,
|
||||||
} from "./validation.js";
|
} from "../../../hosts/managers/validation.js";
|
||||||
import { parseServiceList, buildServiceActionCommand } from "./services.js";
|
import {
|
||||||
import { parseProcessList, buildKillCommand } from "./processes.js";
|
parseServiceList,
|
||||||
import { parseDfMounts, parseTopMemory } from "./simple-reads.js";
|
buildServiceActionCommand,
|
||||||
|
} from "../../../hosts/managers/services.js";
|
||||||
|
import {
|
||||||
|
parseProcessList,
|
||||||
|
buildKillCommand,
|
||||||
|
} from "../../../hosts/managers/processes.js";
|
||||||
|
import {
|
||||||
|
parseDfMounts,
|
||||||
|
parseTopMemory,
|
||||||
|
} from "../../../hosts/managers/simple-reads.js";
|
||||||
import {
|
import {
|
||||||
parseCrontab,
|
parseCrontab,
|
||||||
serializeCrontab,
|
serializeCrontab,
|
||||||
isValidCronSchedule,
|
isValidCronSchedule,
|
||||||
buildApplyCrontabCommand,
|
buildApplyCrontabCommand,
|
||||||
} from "./cron.js";
|
} from "../../../hosts/managers/cron.js";
|
||||||
import {
|
import {
|
||||||
buildPackageActionCommand,
|
buildPackageActionCommand,
|
||||||
parseUpgradable,
|
parseUpgradable,
|
||||||
buildListUpgradableCommand,
|
buildListUpgradableCommand,
|
||||||
} from "./packages.js";
|
} from "../../../hosts/managers/packages.js";
|
||||||
import {
|
import {
|
||||||
buildIssueCommand,
|
buildIssueCommand,
|
||||||
buildRenewCommand,
|
buildRenewCommand,
|
||||||
buildRevokeCommand,
|
buildRevokeCommand,
|
||||||
isValidCertName,
|
isValidCertName,
|
||||||
parseCertbotCertificates,
|
parseCertbotCertificates,
|
||||||
} from "./ssl.js";
|
} from "../../../hosts/managers/ssl.js";
|
||||||
import { buildIptablesRuleCommand, buildNftRuleCommand } from "./firewall.js";
|
import {
|
||||||
import { parsePasswd, parseSudoers } from "./users.js";
|
buildIptablesRuleCommand,
|
||||||
import { buildHealthCheckCommand, parseHealthResult } from "./health.js";
|
buildNftRuleCommand,
|
||||||
import { buildTailCommand, clampLines } from "./logs.js";
|
} from "../../../hosts/managers/firewall.js";
|
||||||
|
import { parsePasswd, parseSudoers } from "../../../hosts/managers/users.js";
|
||||||
|
import {
|
||||||
|
buildHealthCheckCommand,
|
||||||
|
parseHealthResult,
|
||||||
|
} from "../../../hosts/managers/health.js";
|
||||||
|
import { buildTailCommand, clampLines } from "../../../hosts/managers/logs.js";
|
||||||
|
|
||||||
describe("exec-elevated", () => {
|
describe("exec-elevated", () => {
|
||||||
it("single-quotes and escapes for the shell", () => {
|
it("single-quotes and escapes for the shell", () => {
|
||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
resolveHostForSshConnect,
|
resolveHostForSshConnect,
|
||||||
resolveSshConnectConfigHost,
|
resolveSshConnectConfigHost,
|
||||||
shouldResolveBeforeSshConnect,
|
shouldResolveBeforeSshConnect,
|
||||||
} from "./ssh-dns.js";
|
} from "../../hosts/ssh-dns.js";
|
||||||
|
|
||||||
describe("SSH DNS resolution", () => {
|
describe("SSH DNS resolution", () => {
|
||||||
it("retries transient EAI_AGAIN errors before returning an address", async () => {
|
it("retries transient EAI_AGAIN errors before returning an address", async () => {
|
||||||
+1
-1
@@ -6,7 +6,7 @@ vi.mock("fs/promises", () => ({
|
|||||||
access: mockAccess,
|
access: mockAccess,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { resolveAgentSocket } from "./terminal-auth-helpers.js";
|
import { resolveAgentSocket } from "../../hosts/terminal-auth-helpers.js";
|
||||||
|
|
||||||
describe("resolveAgentSocket", () => {
|
describe("resolveAgentSocket", () => {
|
||||||
const originalEnv = process.env.SSH_AUTH_SOCK;
|
const originalEnv = process.env.SSH_AUTH_SOCK;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { performPortKnocking } from "./terminal-auth-helpers.js";
|
import { performPortKnocking } from "../../hosts/terminal-auth-helpers.js";
|
||||||
|
|
||||||
class FakeTcpSocket extends EventEmitter {
|
class FakeTcpSocket extends EventEmitter {
|
||||||
readonly connect = vi.fn();
|
readonly connect = vi.fn();
|
||||||
+5
-4
@@ -4,18 +4,18 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
|
|||||||
const mockCreate = vi.fn().mockResolvedValue({ id: 1 });
|
const mockCreate = vi.fn().mockResolvedValue({ id: 1 });
|
||||||
const mockUpdateEnded = vi.fn().mockResolvedValue(undefined);
|
const mockUpdateEnded = vi.fn().mockResolvedValue(undefined);
|
||||||
|
|
||||||
vi.mock("../database/db/index.js", () => ({
|
vi.mock("../../database/db/index.js", () => ({
|
||||||
getDb: () => ({}),
|
getDb: () => ({}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../database/repositories/factory.js", () => ({
|
vi.mock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentSessionRecordingRepository: () => ({
|
createCurrentSessionRecordingRepository: () => ({
|
||||||
create: mockCreate,
|
create: mockCreate,
|
||||||
updateEnded: mockUpdateEnded,
|
updateEnded: mockUpdateEnded,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../utils/logger.js", () => ({
|
vi.mock("../../utils/logger.js", () => ({
|
||||||
sshLogger: {
|
sshLogger: {
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
warn: vi.fn(),
|
warn: vi.fn(),
|
||||||
@@ -49,7 +49,8 @@ vi.mock("fs", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { sessionManager } = await import("./terminal-session-manager.js");
|
const { sessionManager } =
|
||||||
|
await import("../../hosts/terminal-session-manager.js");
|
||||||
|
|
||||||
describe("TerminalSessionManager - session logging", () => {
|
describe("TerminalSessionManager - session logging", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import { EventEmitter } from "node:events";
|
import { EventEmitter } from "node:events";
|
||||||
import type { Client } from "ssh2";
|
import type { Client } from "ssh2";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { detectTmux, tmuxCommand, withTmuxPath } from "./tmux-helper.js";
|
import {
|
||||||
|
detectTmux,
|
||||||
|
tmuxCommand,
|
||||||
|
withTmuxPath,
|
||||||
|
} from "../../hosts/tmux-helper.js";
|
||||||
|
|
||||||
describe("tmux command path handling", () => {
|
describe("tmux command path handling", () => {
|
||||||
it("adds common non-login shell tmux paths", () => {
|
it("adds common non-login shell tmux paths", () => {
|
||||||
+1
-1
@@ -9,7 +9,7 @@ import {
|
|||||||
buildPaneMetrics,
|
buildPaneMetrics,
|
||||||
attachPanesToWindows,
|
attachPanesToWindows,
|
||||||
shellEscape,
|
shellEscape,
|
||||||
} from "./tmux-monitor-helpers.js";
|
} from "../../hosts/tmux-monitor-helpers.js";
|
||||||
|
|
||||||
function join(...fields: (string | number)[]): string {
|
function join(...fields: (string | number)[]): string {
|
||||||
return fields.join(SEP);
|
return fields.join(SEP);
|
||||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
|||||||
completeVaultOidc,
|
completeVaultOidc,
|
||||||
signWithVault,
|
signWithVault,
|
||||||
type VaultProfileConfig,
|
type VaultProfileConfig,
|
||||||
} from "./vault-signer-core.js";
|
} from "../../hosts/vault-signer-core.js";
|
||||||
|
|
||||||
const { utils: ssh2Utils } = ssh2Pkg;
|
const { utils: ssh2Utils } = ssh2Pkg;
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { toFixedNum, kibToGiB } from "./common-utils.js";
|
import { toFixedNum, kibToGiB } from "../../../hosts/widgets/common-utils.js";
|
||||||
|
|
||||||
describe("toFixedNum", () => {
|
describe("toFixedNum", () => {
|
||||||
it("rounds to the requested digit count", () => {
|
it("rounds to the requested digit count", () => {
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { parseCpuLine } from "./cpu-collector.js";
|
import { parseCpuLine } from "../../../hosts/widgets/cpu-collector.js";
|
||||||
|
|
||||||
describe("parseCpuLine", () => {
|
describe("parseCpuLine", () => {
|
||||||
it("parses a standard /proc/stat cpu line", () => {
|
it("parses a standard /proc/stat cpu line", () => {
|
||||||
+1
-1
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
import {
|
import {
|
||||||
parseSensorsOutput,
|
parseSensorsOutput,
|
||||||
parseSysfsThermalOutput,
|
parseSysfsThermalOutput,
|
||||||
} from "./temperature-collector.js";
|
} from "../../../hosts/widgets/temperature-collector.js";
|
||||||
|
|
||||||
describe("temperature collectors", () => {
|
describe("temperature collectors", () => {
|
||||||
it("parses sysfs thermal zone output", () => {
|
it("parses sysfs thermal zone output", () => {
|
||||||
+2
-2
@@ -2,13 +2,13 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
|
|||||||
|
|
||||||
const createMock = vi.fn().mockResolvedValue(undefined);
|
const createMock = vi.fn().mockResolvedValue(undefined);
|
||||||
|
|
||||||
vi.mock("../database/repositories/factory.js", () => ({
|
vi.mock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentAuditLogRepository: vi.fn(() => ({
|
createCurrentAuditLogRepository: vi.fn(() => ({
|
||||||
create: createMock,
|
create: createMock,
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { logAudit, getRequestMeta } from "./audit-logger.js";
|
import { logAudit, getRequestMeta } from "../../utils/audit-logger.js";
|
||||||
|
|
||||||
describe("logAudit", () => {
|
describe("logAudit", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
+6
-6
@@ -11,7 +11,7 @@ const mocks = vi.hoisted(() => ({
|
|||||||
saveDatabase: vi.fn().mockResolvedValue(undefined),
|
saveDatabase: vi.fn().mockResolvedValue(undefined),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../database/db/index.js", async () => {
|
vi.mock("../../database/db/index.js", async () => {
|
||||||
const { default: Database } = await import("better-sqlite3");
|
const { default: Database } = await import("better-sqlite3");
|
||||||
const { drizzle } = await import("drizzle-orm/better-sqlite3");
|
const { drizzle } = await import("drizzle-orm/better-sqlite3");
|
||||||
const sqlite = new Database(":memory:");
|
const sqlite = new Database(":memory:");
|
||||||
@@ -24,7 +24,7 @@ vi.mock("../database/db/index.js", async () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
vi.mock("./user-keys.js", () => ({
|
vi.mock("../../utils/user-keys.js", () => ({
|
||||||
UserKeyManager: {
|
UserKeyManager: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
invalidate: vi.fn(),
|
invalidate: vi.fn(),
|
||||||
@@ -34,15 +34,15 @@ vi.mock("./user-keys.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./system-crypto.js", () => ({
|
vi.mock("../../utils/system-crypto.js", () => ({
|
||||||
SystemCrypto: { getInstance: () => ({}) },
|
SystemCrypto: { getInstance: () => ({}) },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./data-crypto.js", () => ({
|
vi.mock("../../utils/data-crypto.js", () => ({
|
||||||
DataCrypto: { getInstance: () => ({}) },
|
DataCrypto: { getInstance: () => ({}) },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./logger.js", () => ({
|
vi.mock("../../utils/logger.js", () => ({
|
||||||
authLogger: {
|
authLogger: {
|
||||||
debug: vi.fn(),
|
debug: vi.fn(),
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
@@ -59,7 +59,7 @@ vi.mock("./logger.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { AuthManager } = await import("./auth-manager.js");
|
const { AuthManager } = await import("../../utils/auth-manager.js");
|
||||||
const authManager = AuthManager.getInstance();
|
const authManager = AuthManager.getInstance();
|
||||||
|
|
||||||
type SessionInput = {
|
type SessionInput = {
|
||||||
+6
-6
@@ -10,13 +10,13 @@ const mocks = vi.hoisted(() => ({
|
|||||||
adoptRecoveredDEK: vi.fn(async () => {}),
|
adoptRecoveredDEK: vi.fn(async () => {}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../database/db/index.js", () => ({
|
vi.mock("../../database/db/index.js", () => ({
|
||||||
db: {},
|
db: {},
|
||||||
getDb: () => ({}),
|
getDb: () => ({}),
|
||||||
saveMemoryDatabaseToFile: vi.fn(),
|
saveMemoryDatabaseToFile: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../database/repositories/factory.js", () => ({
|
vi.mock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentSettingsRepository: () => ({ get: async () => null }),
|
createCurrentSettingsRepository: () => ({ get: async () => null }),
|
||||||
createCurrentSessionRepository: () => ({}),
|
createCurrentSessionRepository: () => ({}),
|
||||||
createCurrentUserRepository: () => ({}),
|
createCurrentUserRepository: () => ({}),
|
||||||
@@ -25,7 +25,7 @@ vi.mock("../database/repositories/factory.js", () => ({
|
|||||||
getCurrentSettingValue: () => null,
|
getCurrentSettingValue: () => null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./user-keys.js", () => ({
|
vi.mock("../../utils/user-keys.js", () => ({
|
||||||
UserKeyManager: {
|
UserKeyManager: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
hasUserDEK: mocks.hasUserDEK,
|
hasUserDEK: mocks.hasUserDEK,
|
||||||
@@ -35,12 +35,12 @@ vi.mock("./user-keys.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./crypto-migration/dek-migration.js", () => ({
|
vi.mock("../../utils/crypto-migration/dek-migration.js", () => ({
|
||||||
adoptRecoveredDEK: mocks.adoptRecoveredDEK,
|
adoptRecoveredDEK: mocks.adoptRecoveredDEK,
|
||||||
migratePasswordUserAtLogin: vi.fn(async () => true),
|
migratePasswordUserAtLogin: vi.fn(async () => true),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./system-crypto.js", () => ({
|
vi.mock("../../utils/system-crypto.js", () => ({
|
||||||
SystemCrypto: {
|
SystemCrypto: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
getJWTSecret: async () => jwtSecret,
|
getJWTSecret: async () => jwtSecret,
|
||||||
@@ -49,7 +49,7 @@ vi.mock("./system-crypto.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { AuthManager } = await import("./auth-manager.js");
|
const { AuthManager } = await import("../../utils/auth-manager.js");
|
||||||
const authManager = AuthManager.getInstance();
|
const authManager = AuthManager.getInstance();
|
||||||
|
|
||||||
function makeLegacyDataKeyWrap(
|
function makeLegacyDataKeyWrap(
|
||||||
+4
-4
@@ -4,7 +4,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
|||||||
const settingsStore = new Map<string, string>();
|
const settingsStore = new Map<string, string>();
|
||||||
let userRows: Array<{ id: string }> = [];
|
let userRows: Array<{ id: string }> = [];
|
||||||
|
|
||||||
vi.mock("../../database/repositories/factory.js", () => ({
|
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||||
getCurrentSettingValue: (key: string) => settingsStore.get(key) ?? null,
|
getCurrentSettingValue: (key: string) => settingsStore.get(key) ?? null,
|
||||||
createCurrentSettingsRepository: () => ({
|
createCurrentSettingsRepository: () => ({
|
||||||
upsert: async (key: string, value: string) => {
|
upsert: async (key: string, value: string) => {
|
||||||
@@ -24,7 +24,7 @@ vi.mock("../../database/repositories/factory.js", () => ({
|
|||||||
|
|
||||||
const masterKey = crypto.randomBytes(32);
|
const masterKey = crypto.randomBytes(32);
|
||||||
|
|
||||||
vi.mock("../system-crypto.js", () => ({
|
vi.mock("../../../utils/system-crypto.js", () => ({
|
||||||
SystemCrypto: {
|
SystemCrypto: {
|
||||||
getInstance: () => ({
|
getInstance: () => ({
|
||||||
getEncryptionKey: async () => masterKey,
|
getEncryptionKey: async () => masterKey,
|
||||||
@@ -32,13 +32,13 @@ vi.mock("../system-crypto.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { UserKeyManager } from "../user-keys.js";
|
import { UserKeyManager } from "../../../utils/user-keys.js";
|
||||||
import {
|
import {
|
||||||
adoptRecoveredDEK,
|
adoptRecoveredDEK,
|
||||||
legacySettingsKeys,
|
legacySettingsKeys,
|
||||||
migratePasswordUserAtLogin,
|
migratePasswordUserAtLogin,
|
||||||
runBootDekMigration,
|
runBootDekMigration,
|
||||||
} from "./dek-migration.js";
|
} from "../../../utils/crypto-migration/dek-migration.js";
|
||||||
|
|
||||||
const manager = UserKeyManager.getInstance();
|
const manager = UserKeyManager.getInstance();
|
||||||
|
|
||||||
BIN
Binary file not shown.
+1
-1
@@ -7,7 +7,7 @@ import {
|
|||||||
DATABASE_LAYER_PREUPGRADE_BACKUP_PREFIX,
|
DATABASE_LAYER_PREUPGRADE_BACKUP_PREFIX,
|
||||||
DATABASE_LAYER_SKIP_PREUPGRADE_BACKUP_ENV,
|
DATABASE_LAYER_SKIP_PREUPGRADE_BACKUP_ENV,
|
||||||
ensureDatabaseLayerPreupgradeBackup,
|
ensureDatabaseLayerPreupgradeBackup,
|
||||||
} from "./database-layer-preupgrade-backup.js";
|
} from "../../utils/database-layer-preupgrade-backup.js";
|
||||||
|
|
||||||
const tempDirs: string[] = [];
|
const tempDirs: string[] = [];
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import { DatabaseSaveTrigger } from "./database-save-trigger.js";
|
import { DatabaseSaveTrigger } from "../../utils/database-save-trigger.js";
|
||||||
|
|
||||||
describe("DatabaseSaveTrigger", () => {
|
describe("DatabaseSaveTrigger", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import { FieldCrypto } from "./field-crypto.js";
|
import { FieldCrypto } from "../../utils/field-crypto.js";
|
||||||
|
|
||||||
const masterKey = crypto.randomBytes(32);
|
const masterKey = crypto.randomBytes(32);
|
||||||
|
|
||||||
+1
-1
@@ -3,7 +3,7 @@ import fs from "fs";
|
|||||||
import os from "os";
|
import os from "os";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import { LegacySqliteDatabaseCopyStore } from "./legacy-sqlite-database-copy-store.js";
|
import { LegacySqliteDatabaseCopyStore } from "../../utils/legacy-sqlite-database-copy-store.js";
|
||||||
|
|
||||||
describe("LegacySqliteDatabaseCopyStore", () => {
|
describe("LegacySqliteDatabaseCopyStore", () => {
|
||||||
let tempDir: string | null = null;
|
let tempDir: string | null = null;
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { describe, it, expect, beforeEach } from "vitest";
|
import { describe, it, expect, beforeEach } from "vitest";
|
||||||
import { loginRateLimiter } from "./login-rate-limiter.js";
|
import { loginRateLimiter } from "../../utils/login-rate-limiter.js";
|
||||||
|
|
||||||
// The limiter is a shared singleton, so each test uses unique ip/username keys
|
// The limiter is a shared singleton, so each test uses unique ip/username keys
|
||||||
// and resets them to stay isolated.
|
// and resets them to stay isolated.
|
||||||
+1
-1
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
import {
|
import {
|
||||||
getDesktopOidcCallbackUrl,
|
getDesktopOidcCallbackUrl,
|
||||||
isOidcTokenCallback,
|
isOidcTokenCallback,
|
||||||
} from "./oidc-desktop-callback";
|
} from "../../utils/oidc-desktop-callback.js";
|
||||||
|
|
||||||
describe("getDesktopOidcCallbackUrl", () => {
|
describe("getDesktopOidcCallbackUrl", () => {
|
||||||
it("uses localhost so browsers do not upgrade the loopback callback", () => {
|
it("uses localhost so browsers do not upgrade the loopback callback", () => {
|
||||||
+3
-3
@@ -4,8 +4,8 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
|
|||||||
// top level. Stub both so importing the module does not spin up the real
|
// top level. Stub both so importing the module does not spin up the real
|
||||||
// database / encryption stack. We then drive hasPermission via a spied
|
// database / encryption stack. We then drive hasPermission via a spied
|
||||||
// getUserPermissions so we test the wildcard-matching logic in isolation.
|
// getUserPermissions so we test the wildcard-matching logic in isolation.
|
||||||
vi.mock("../database/db/index.js", () => ({ db: {} }));
|
vi.mock("../../database/db/index.js", () => ({ db: {} }));
|
||||||
vi.mock("./logger.js", () => ({
|
vi.mock("../../utils/logger.js", () => ({
|
||||||
databaseLogger: {
|
databaseLogger: {
|
||||||
debug: vi.fn(),
|
debug: vi.fn(),
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
@@ -15,7 +15,7 @@ vi.mock("./logger.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { PermissionManager } = await import("./permission-manager.js");
|
const { PermissionManager } = await import("../../utils/permission-manager.js");
|
||||||
|
|
||||||
type PermissionManagerInstance = ReturnType<
|
type PermissionManagerInstance = ReturnType<
|
||||||
typeof PermissionManager.getInstance
|
typeof PermissionManager.getInstance
|
||||||
+1
-1
@@ -5,7 +5,7 @@ import {
|
|||||||
getRequestBaseUrlWithForceHTTPS,
|
getRequestBaseUrlWithForceHTTPS,
|
||||||
getRequestOrigin,
|
getRequestOrigin,
|
||||||
normalizeBasePath,
|
normalizeBasePath,
|
||||||
} from "./request-origin.js";
|
} from "../../utils/request-origin.js";
|
||||||
|
|
||||||
function request(headers: Record<string, string | string[] | undefined>) {
|
function request(headers: Record<string, string | string[] | undefined>) {
|
||||||
return {
|
return {
|
||||||
+4
-4
@@ -9,7 +9,7 @@ const state = vi.hoisted(() => ({
|
|||||||
ownerCredential: null as Record<string, unknown> | null,
|
ownerCredential: null as Record<string, unknown> | null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../database/repositories/factory.js", () => ({
|
vi.mock("../../database/repositories/factory.js", () => ({
|
||||||
createCurrentCredentialRepository: () => ({
|
createCurrentCredentialRepository: () => ({
|
||||||
findByIdForUser: async (_userId: string, _id: number) =>
|
findByIdForUser: async (_userId: string, _id: number) =>
|
||||||
state.ownerCredential,
|
state.ownerCredential,
|
||||||
@@ -38,7 +38,7 @@ vi.mock("../database/repositories/factory.js", () => ({
|
|||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("./data-crypto.js", () => ({
|
vi.mock("../../utils/data-crypto.js", () => ({
|
||||||
DataCrypto: {
|
DataCrypto: {
|
||||||
validateUserAccess: (userId: string) => {
|
validateUserAccess: (userId: string) => {
|
||||||
if (userId === "owner") return ownerDEK;
|
if (userId === "owner") return ownerDEK;
|
||||||
@@ -51,8 +51,8 @@ vi.mock("./data-crypto.js", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { FieldCrypto } from "./field-crypto.js";
|
import { FieldCrypto } from "../../utils/field-crypto.js";
|
||||||
import { SharedCredentialManager } from "./shared-credential-manager.js";
|
import { SharedCredentialManager } from "../../utils/shared-credential-manager.js";
|
||||||
|
|
||||||
const manager = SharedCredentialManager.getInstance();
|
const manager = SharedCredentialManager.getInstance();
|
||||||
|
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
|||||||
preparePrivateKeyForSSH2,
|
preparePrivateKeyForSSH2,
|
||||||
getFriendlyKeyTypeName,
|
getFriendlyKeyTypeName,
|
||||||
validateKeyPair,
|
validateKeyPair,
|
||||||
} from "./ssh-key-utils.js";
|
} from "../../utils/ssh-key-utils.js";
|
||||||
|
|
||||||
// A real OpenSSH ed25519 keypair generated solely for these tests. It grants no
|
// A real OpenSSH ed25519 keypair generated solely for these tests. It grants no
|
||||||
// access to anything and exists only so the ssh2 parsing path is exercised for
|
// access to anything and exists only so the ssh2 parsing path is exercised for
|
||||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
|||||||
detectPlatform,
|
detectPlatform,
|
||||||
parseUserAgent,
|
parseUserAgent,
|
||||||
generateDeviceFingerprint,
|
generateDeviceFingerprint,
|
||||||
} from "./user-agent-parser.js";
|
} from "../../utils/user-agent-parser.js";
|
||||||
|
|
||||||
function reqWith(headers: Record<string, string>): Request {
|
function reqWith(headers: Record<string, string>): Request {
|
||||||
return { headers } as unknown as Request;
|
return { headers } as unknown as Request;
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { RawSqliteUserEncryptionMigrationStore } from "./user-encryption-migration-store.js";
|
import { RawSqliteUserEncryptionMigrationStore } from "../../utils/user-encryption-migration-store.js";
|
||||||
|
|
||||||
describe("RawSqliteUserEncryptionMigrationStore", () => {
|
describe("RawSqliteUserEncryptionMigrationStore", () => {
|
||||||
function createDb() {
|
function createDb() {
|
||||||
@@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
|||||||
|
|
||||||
const settingsStore = new Map<string, string>();
|
const settingsStore = new Map<string, string>();
|
||||||
|
|
||||||
vi.mock("../database/repositories/factory.js", () => ({
|
vi.mock("../../database/repositories/factory.js", () => ({
|
||||||
getCurrentSettingValue: (key: string) => settingsStore.get(key) ?? null,
|
getCurrentSettingValue: (key: string) => settingsStore.get(key) ?? null,
|
||||||
createCurrentSettingsRepository: () => ({
|
createCurrentSettingsRepository: () => ({
|
||||||
upsert: async (key: string, value: string) => {
|
upsert: async (key: string, value: string) => {
|
||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
UserKeyManager,
|
UserKeyManager,
|
||||||
UserKeyUnavailableError,
|
UserKeyUnavailableError,
|
||||||
userDekSettingsKey,
|
userDekSettingsKey,
|
||||||
} from "./user-keys.js";
|
} from "../../utils/user-keys.js";
|
||||||
|
|
||||||
const masterKey = crypto.randomBytes(32);
|
const masterKey = crypto.randomBytes(32);
|
||||||
const manager = UserKeyManager.getInstance();
|
const manager = UserKeyManager.getInstance();
|
||||||
@@ -12,7 +12,11 @@ vi.mock("dgram", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
import dgram from "dgram";
|
import dgram from "dgram";
|
||||||
import { isValidMac, buildMagicPacket, sendWakeOnLan } from "./wake-on-lan.js";
|
import {
|
||||||
|
isValidMac,
|
||||||
|
buildMagicPacket,
|
||||||
|
sendWakeOnLan,
|
||||||
|
} from "../../utils/wake-on-lan.js";
|
||||||
|
|
||||||
describe("isValidMac", () => {
|
describe("isValidMac", () => {
|
||||||
it("accepts colon-separated MAC addresses", () => {
|
it("accepts colon-separated MAC addresses", () => {
|
||||||
Reference in New Issue
Block a user