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 { TestSqliteDatabase } from "./test-support.js";
|
||||
import { AlertRepository } from "./alert-repository.js";
|
||||
import { AlertRepository } from "../../../database/repositories/alert-repository.js";
|
||||
|
||||
describe("AlertRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { ApiKeyRepository } from "./api-key-repository.js";
|
||||
import { ApiKeyRepository } from "../../../database/repositories/api-key-repository.js";
|
||||
|
||||
describe("ApiKeyRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { AuditLogRepository } from "./audit-log-repository.js";
|
||||
import { AuditLogRepository } from "../../../database/repositories/audit-log-repository.js";
|
||||
|
||||
describe("AuditLogRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { CommandHistoryRepository } from "./command-history-repository.js";
|
||||
import { CommandHistoryRepository } from "../../../database/repositories/command-history-repository.js";
|
||||
|
||||
describe("CommandHistoryRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { DismissedAlertRepository } from "./dismissed-alert-repository.js";
|
||||
import { DismissedAlertRepository } from "../../../database/repositories/dismissed-alert-repository.js";
|
||||
|
||||
describe("DismissedAlertRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import crypto from "crypto";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { FieldEncryptionBoundary } from "./field-encryption-boundary.js";
|
||||
import { FieldEncryptionBoundary } from "../../../database/repositories/field-encryption-boundary.js";
|
||||
|
||||
describe("FieldEncryptionBoundary", () => {
|
||||
const userDataKey = crypto.randomBytes(32);
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { HomepageItemRepository } from "./homepage-item-repository.js";
|
||||
import { HomepageItemRepository } from "../../../database/repositories/homepage-item-repository.js";
|
||||
|
||||
describe("HomepageItemRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { HomepageLayoutRepository } from "./homepage-layout-repository.js";
|
||||
import { HomepageLayoutRepository } from "../../../database/repositories/homepage-layout-repository.js";
|
||||
|
||||
describe("HomepageLayoutRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { CredentialRepository } from "./credential-repository.js";
|
||||
import { HostRepository } from "./host-repository.js";
|
||||
import { DataCrypto } from "../../utils/data-crypto.js";
|
||||
import { CredentialRepository } from "../../../database/repositories/credential-repository.js";
|
||||
import { HostRepository } from "../../../database/repositories/host-repository.js";
|
||||
import { DataCrypto } from "../../../utils/data-crypto.js";
|
||||
|
||||
describe("HostRepository and CredentialRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { HostFolderRepository } from "./host-folder-repository.js";
|
||||
import { HostFolderRepository } from "../../../database/repositories/host-folder-repository.js";
|
||||
|
||||
describe("HostFolderRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { HostHealthRepository } from "./host-health-repository.js";
|
||||
import { HostHealthRepository } from "../../../database/repositories/host-health-repository.js";
|
||||
|
||||
describe("HostHealthRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { DataCrypto } from "../../utils/data-crypto.js";
|
||||
import { HostResolutionRepository } from "./host-resolution-repository.js";
|
||||
import { DataCrypto } from "../../../utils/data-crypto.js";
|
||||
import { HostResolutionRepository } from "../../../database/repositories/host-resolution-repository.js";
|
||||
|
||||
vi.mock("../../utils/data-crypto.js", () => ({
|
||||
vi.mock("../../../utils/data-crypto.js", () => ({
|
||||
DataCrypto: {
|
||||
getUserDataKey: vi.fn(),
|
||||
decryptRecord: vi.fn((_tableName, record) => record),
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { NetworkTopologyRepository } from "./network-topology-repository.js";
|
||||
import { NetworkTopologyRepository } from "../../../database/repositories/network-topology-repository.js";
|
||||
|
||||
describe("NetworkTopologyRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { OpenTabRepository } from "./open-tab-repository.js";
|
||||
import { OpenTabRepository } from "../../../database/repositories/open-tab-repository.js";
|
||||
|
||||
describe("OpenTabRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { OpksshTokenRepository } from "./opkssh-token-repository.js";
|
||||
import { OpksshTokenRepository } from "../../../database/repositories/opkssh-token-repository.js";
|
||||
|
||||
describe("OpksshTokenRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { RbacAccessRepository } from "./rbac-access-repository.js";
|
||||
import { RbacAccessRepository } from "../../../database/repositories/rbac-access-repository.js";
|
||||
|
||||
describe("RbacAccessRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { RecentActivityRepository } from "./recent-activity-repository.js";
|
||||
import { RecentActivityRepository } from "../../../database/repositories/recent-activity-repository.js";
|
||||
|
||||
describe("RecentActivityRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { RoleRepository } from "./role-repository.js";
|
||||
import { RoleRepository } from "../../../database/repositories/role-repository.js";
|
||||
|
||||
describe("RoleRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { SessionRecordingRepository } from "./session-recording-repository.js";
|
||||
import { SessionRecordingRepository } from "../../../database/repositories/session-recording-repository.js";
|
||||
|
||||
describe("SessionRecordingRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { SettingsRepository } from "./settings-repository.js";
|
||||
import { SettingsRepository } from "../../../database/repositories/settings-repository.js";
|
||||
|
||||
describe("SettingsRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { SharedCredentialRepository } from "./shared-credential-repository.js";
|
||||
import { SharedCredentialRepository } from "../../../database/repositories/shared-credential-repository.js";
|
||||
|
||||
describe("SharedCredentialRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { SnippetRepository } from "./snippet-repository.js";
|
||||
import { SnippetRepository } from "../../../database/repositories/snippet-repository.js";
|
||||
|
||||
describe("SnippetRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { SsoProviderRepository } from "./sso-provider-repository.js";
|
||||
import { SsoProviderRepository } from "../../../database/repositories/sso-provider-repository.js";
|
||||
|
||||
describe("SsoProviderRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { DataCrypto } from "../../utils/data-crypto.js";
|
||||
import { TermixIdentityCaRepository } from "./termix-identity-ca-repository.js";
|
||||
import { DataCrypto } from "../../../utils/data-crypto.js";
|
||||
import { TermixIdentityCaRepository } from "../../../database/repositories/termix-identity-ca-repository.js";
|
||||
|
||||
describe("TermixIdentityCaRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { TermixIdentityRepository } from "./termix-identity-repository.js";
|
||||
import { TermixIdentityRepository } from "../../../database/repositories/termix-identity-repository.js";
|
||||
|
||||
describe("TermixIdentityRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import Database from "better-sqlite3";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import * as schema from "../db/schema.js";
|
||||
import type { DatabaseContext } from "./database-context.js";
|
||||
import * as schema from "../../../database/db/schema.js";
|
||||
import type { DatabaseContext } from "../../../database/repositories/database-context.js";
|
||||
|
||||
export class TestSqliteDatabase {
|
||||
private sqlite: Database.Database | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { TransferRecentRepository } from "./transfer-recent-repository.js";
|
||||
import { TransferRecentRepository } from "../../../database/repositories/transfer-recent-repository.js";
|
||||
|
||||
describe("TransferRecentRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { TrustedDeviceRepository } from "./trusted-device-repository.js";
|
||||
import { TrustedDeviceRepository } from "../../../database/repositories/trusted-device-repository.js";
|
||||
|
||||
describe("TrustedDeviceRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
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", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { UserPreferenceRepository } from "./user-preference-repository.js";
|
||||
import { UserPreferenceRepository } from "../../../database/repositories/user-preference-repository.js";
|
||||
|
||||
describe("UserPreferenceRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { SessionRepository } from "./session-repository.js";
|
||||
import { UserRepository } from "./user-repository.js";
|
||||
import { SessionRepository } from "../../../database/repositories/session-repository.js";
|
||||
import { UserRepository } from "../../../database/repositories/user-repository.js";
|
||||
|
||||
describe("UserRepository and SessionRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { VaultProfileRepository } from "./vault-profile-repository.js";
|
||||
import { VaultProfileRepository } from "../../../database/repositories/vault-profile-repository.js";
|
||||
|
||||
describe("VaultProfileRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { TestSqliteDatabase } from "./test-support.js";
|
||||
import { VaultTokenRepository } from "./vault-token-repository.js";
|
||||
import { VaultTokenRepository } from "../../../database/repositories/vault-token-repository.js";
|
||||
|
||||
describe("VaultTokenRepository", () => {
|
||||
let adapter: TestSqliteDatabase | null = null;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { parseSSHConfig } from "./host-bulk-routes.js";
|
||||
import { parseSSHConfig } from "../../../database/routes/host-bulk-routes.js";
|
||||
|
||||
describe("parseSSHConfig", () => {
|
||||
it("parses a basic Host block", () => {
|
||||
+2
-2
@@ -4,14 +4,14 @@ const mocks = vi.hoisted(() => ({
|
||||
isUserDataUnlocked: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../../utils/simple-db-ops.js", () => ({
|
||||
vi.mock("../../../utils/simple-db-ops.js", () => ({
|
||||
SimpleDBOps: {
|
||||
isUserDataUnlocked: mocks.isUserDataUnlocked,
|
||||
},
|
||||
}));
|
||||
|
||||
const { applyHostEnrollmentDefaults, requireHostEnrollmentAccessForPath } =
|
||||
await import("./host-enrollment-auth.js");
|
||||
await import("../../../database/routes/host-enrollment-auth.js");
|
||||
|
||||
function response() {
|
||||
const json = vi.fn();
|
||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
||||
renameFolderPath,
|
||||
stripSensitiveFields,
|
||||
transformHostResponse,
|
||||
} from "./host-normalizers.js";
|
||||
} from "../../../database/routes/host-normalizers.js";
|
||||
|
||||
describe("isNonEmptyString", () => {
|
||||
it("accepts non-blank strings", () => {
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
isValidServiceLinkUrl,
|
||||
normalizeServiceLinkUrl,
|
||||
} from "./service-link-url.js";
|
||||
} from "../../../database/routes/service-link-url.js";
|
||||
|
||||
describe("service link URL handling", () => {
|
||||
it("keeps explicit http and https URLs", () => {
|
||||
+5
-4
@@ -6,7 +6,7 @@ const mockSelect = vi.fn();
|
||||
const mockDelete = vi.fn();
|
||||
const mockInsert = vi.fn();
|
||||
|
||||
vi.mock("../db/index.js", () => ({
|
||||
vi.mock("../../../database/db/index.js", () => ({
|
||||
db: {
|
||||
select: mockSelect,
|
||||
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() },
|
||||
}));
|
||||
|
||||
vi.mock("../../utils/auth-manager.js", () => ({
|
||||
vi.mock("../../../utils/auth-manager.js", () => ({
|
||||
AuthManager: {
|
||||
getInstance: () => ({
|
||||
createAuthMiddleware:
|
||||
@@ -92,7 +92,8 @@ describe("session-log-routes", () => {
|
||||
mockStat.mockReturnValue({ size: 4096 });
|
||||
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -8,7 +8,7 @@ import {
|
||||
generateCa,
|
||||
signUserCertificate,
|
||||
ed25519RawFromLine,
|
||||
} from "./ssh-certificate.js";
|
||||
} from "../../../database/routes/ssh-certificate.js";
|
||||
|
||||
function publicKeyObjectFromLine(line: string) {
|
||||
const raw = ed25519RawFromLine(line);
|
||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
||||
parsePublicKey,
|
||||
matchesAlgoFilter,
|
||||
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
|
||||
// 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 mockDelete = vi.fn();
|
||||
|
||||
vi.mock("../db/index.js", () => ({
|
||||
vi.mock("../../../database/db/index.js", () => ({
|
||||
db: {
|
||||
select: mockSelect,
|
||||
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() },
|
||||
authLogger: {
|
||||
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: {
|
||||
getInstance: () => ({
|
||||
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(),
|
||||
getRequestMeta: vi.fn(() => ({})),
|
||||
}));
|
||||
|
||||
vi.mock("../../utils/data-crypto.js", () => ({
|
||||
vi.mock("../../../utils/data-crypto.js", () => ({
|
||||
DataCrypto: { getInstance: () => ({ encrypt: vi.fn(), decrypt: vi.fn() }) },
|
||||
}));
|
||||
|
||||
vi.mock("../repositories/factory.js", () => ({
|
||||
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||
createCurrentTermixIdentityCaRepository: vi.fn(() => ({
|
||||
findPublicByIdentityId: 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() },
|
||||
matchesAlgoFilter: vi.fn(() => true),
|
||||
}));
|
||||
@@ -117,7 +117,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
||||
// First select (getIdentityForUser) returns nothing; second should not be called
|
||||
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();
|
||||
@@ -128,7 +129,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
||||
.mockReturnValueOnce(makeChain([IDENTITY_ROW])) // identity 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();
|
||||
});
|
||||
|
||||
@@ -142,7 +144,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
||||
.mockReturnValueOnce(makeChain([IDENTITY_ROW]))
|
||||
.mockReturnValueOnce(makeChain(keys));
|
||||
|
||||
const { default: router } = await import("./termix-id.js");
|
||||
const { default: router } =
|
||||
await import("../../../database/routes/termix-id.js");
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -152,7 +155,8 @@ describe("GET /termix-id/linked-credentials", () => {
|
||||
.mockReturnValueOnce(makeChain([IDENTITY_ROW]))
|
||||
.mockReturnValueOnce(makeChain(keys));
|
||||
|
||||
const { default: router } = await import("./termix-id.js");
|
||||
const { default: router } =
|
||||
await import("../../../database/routes/termix-id.js");
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
});
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
|
||||
// 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: {
|
||||
debug: vi.fn(),
|
||||
info: vi.fn(),
|
||||
@@ -16,7 +16,7 @@ const {
|
||||
getOIDCConfigFromEnv,
|
||||
extractOidcGroups,
|
||||
validateLogoutTokenClaims,
|
||||
} = await import("./user-oidc-utils.js");
|
||||
} = await import("../../../database/routes/user-oidc-utils.js");
|
||||
|
||||
const BACKCHANNEL_LOGOUT_EVENT =
|
||||
"http://schemas.openid.net/event/backchannel-logout";
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
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(() => ({
|
||||
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: () => ({
|
||||
update: async (userId: string, update: Record<string, unknown>) => {
|
||||
calls.userUpdates.push([userId, update]);
|
||||
@@ -34,7 +34,7 @@ vi.mock("../repositories/factory.js", () => ({
|
||||
createCurrentCredentialRepository: deletingRepo("credentials"),
|
||||
}));
|
||||
|
||||
vi.mock("../../utils/user-keys.js", () => ({
|
||||
vi.mock("../../../utils/user-keys.js", () => ({
|
||||
UserKeyManager: {
|
||||
getInstance: () => ({
|
||||
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) => {
|
||||
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 {
|
||||
return {
|
||||
+4
-3
@@ -6,13 +6,13 @@ import speakeasy from "speakeasy";
|
||||
// importing stays inert.
|
||||
const userRepositoryUpdate = vi.fn().mockResolvedValue(null);
|
||||
|
||||
vi.mock("../repositories/factory.js", () => ({
|
||||
vi.mock("../../../database/repositories/factory.js", () => ({
|
||||
createCurrentUserRepository: () => ({
|
||||
update: userRepositoryUpdate,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("../../utils/logger.js", () => ({
|
||||
vi.mock("../../../utils/logger.js", () => ({
|
||||
authLogger: {
|
||||
debug: 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];
|
||||
|
||||
+7
-7
@@ -3,7 +3,7 @@ import {
|
||||
pickResolvedUsername,
|
||||
pickResolvedPassword,
|
||||
expandOidcUsername,
|
||||
} from "./credential-username.js";
|
||||
} from "../../hosts/credential-username.js";
|
||||
|
||||
describe("pickResolvedUsername", () => {
|
||||
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 () => {
|
||||
vi.doMock("../database/repositories/factory.js", () => ({
|
||||
vi.doMock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentUserRepository: () => ({
|
||||
findById: async () => ({ oidcIdentifier: "jdoe" }),
|
||||
}),
|
||||
}));
|
||||
|
||||
const { expandOidcUsername: expand } =
|
||||
await import("./credential-username.js");
|
||||
await import("../../hosts/credential-username.js");
|
||||
expect(await expand("$oidc.preferred_username", "user-1")).toBe("jdoe");
|
||||
});
|
||||
|
||||
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: () => ({
|
||||
findById: async () => ({ oidcIdentifier: null }),
|
||||
}),
|
||||
}));
|
||||
|
||||
const { expandOidcUsername: expand } =
|
||||
await import("./credential-username.js");
|
||||
await import("../../hosts/credential-username.js");
|
||||
expect(await expand("$oidc.preferred_username", "user-1")).toBe(
|
||||
"$oidc.preferred_username",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns the username unchanged when the DB lookup throws", async () => {
|
||||
vi.doMock("../database/repositories/factory.js", () => ({
|
||||
vi.doMock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentUserRepository: () => {
|
||||
throw new Error("DB unavailable");
|
||||
},
|
||||
}));
|
||||
|
||||
const { expandOidcUsername: expand } =
|
||||
await import("./credential-username.js");
|
||||
await import("../../hosts/credential-username.js");
|
||||
expect(await expand("$oidc.preferred_username", "user-1")).toBe(
|
||||
"$oidc.preferred_username",
|
||||
);
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
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", () => {
|
||||
it("builds a PowerShell 5.1 compatible delete command for Windows files", () => {
|
||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
||||
getMimeType,
|
||||
detectBinary,
|
||||
parseLsDateToTimestamp,
|
||||
} from "./file-manager-utils.js";
|
||||
} from "../../hosts/file-manager-utils.js";
|
||||
|
||||
describe("isExecutableFile", () => {
|
||||
it("flags scripts with execute permission", () => {
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("../../utils/logger.js", () => ({
|
||||
vi.mock("../../../utils/logger.js", () => ({
|
||||
guacLogger: {
|
||||
debug: 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", () => {
|
||||
const tokenService = GuacamoleTokenService.getInstance();
|
||||
+2
-2
@@ -4,8 +4,8 @@ import {
|
||||
supportsMetrics,
|
||||
isTcpPingEnabled,
|
||||
tcpPingThroughJumpHost,
|
||||
} from "./host-metrics-helpers.js";
|
||||
import { createConnectionLog } from "./connection-log.js";
|
||||
} from "../../hosts/host-metrics-helpers.js";
|
||||
import { createConnectionLog } from "../../hosts/connection-log.js";
|
||||
|
||||
describe("supportsMetrics", () => {
|
||||
it("supports plain ssh hosts", () => {
|
||||
+1
-1
@@ -5,7 +5,7 @@ import {
|
||||
isMetricCardId,
|
||||
isManagerCardId,
|
||||
METRIC_CARD_IDS,
|
||||
} from "../../types/host-metrics.js";
|
||||
} from "../../../types/host-metrics.js";
|
||||
|
||||
describe("deriveEnabledWidgets", () => {
|
||||
it("returns only metric ids, in canonical order, deduped", () => {
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
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", () => {
|
||||
it("never exceeds max concurrent runners", async () => {
|
||||
+5
-2
@@ -1,11 +1,14 @@
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
|
||||
const execCommand = vi.fn();
|
||||
vi.mock("../widgets/common-utils.js", () => ({
|
||||
vi.mock("../../../hosts/widgets/common-utils.js", () => ({
|
||||
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";
|
||||
|
||||
const fakeClient = {} as Client;
|
||||
+31
-13
@@ -1,6 +1,9 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { buildSudoCommand, shellSingleQuote } from "./exec-elevated.js";
|
||||
import { parsePlatformProbe } from "./platform.js";
|
||||
import {
|
||||
buildSudoCommand,
|
||||
shellSingleQuote,
|
||||
} from "../../../hosts/managers/exec-elevated.js";
|
||||
import { parsePlatformProbe } from "../../../hosts/managers/platform.js";
|
||||
import {
|
||||
isValidSystemdUnit,
|
||||
isValidPid,
|
||||
@@ -12,32 +15,47 @@ import {
|
||||
isValidSignal,
|
||||
isValidServiceAction,
|
||||
isAllowedPath,
|
||||
} from "./validation.js";
|
||||
import { parseServiceList, buildServiceActionCommand } from "./services.js";
|
||||
import { parseProcessList, buildKillCommand } from "./processes.js";
|
||||
import { parseDfMounts, parseTopMemory } from "./simple-reads.js";
|
||||
} from "../../../hosts/managers/validation.js";
|
||||
import {
|
||||
parseServiceList,
|
||||
buildServiceActionCommand,
|
||||
} from "../../../hosts/managers/services.js";
|
||||
import {
|
||||
parseProcessList,
|
||||
buildKillCommand,
|
||||
} from "../../../hosts/managers/processes.js";
|
||||
import {
|
||||
parseDfMounts,
|
||||
parseTopMemory,
|
||||
} from "../../../hosts/managers/simple-reads.js";
|
||||
import {
|
||||
parseCrontab,
|
||||
serializeCrontab,
|
||||
isValidCronSchedule,
|
||||
buildApplyCrontabCommand,
|
||||
} from "./cron.js";
|
||||
} from "../../../hosts/managers/cron.js";
|
||||
import {
|
||||
buildPackageActionCommand,
|
||||
parseUpgradable,
|
||||
buildListUpgradableCommand,
|
||||
} from "./packages.js";
|
||||
} from "../../../hosts/managers/packages.js";
|
||||
import {
|
||||
buildIssueCommand,
|
||||
buildRenewCommand,
|
||||
buildRevokeCommand,
|
||||
isValidCertName,
|
||||
parseCertbotCertificates,
|
||||
} from "./ssl.js";
|
||||
import { buildIptablesRuleCommand, buildNftRuleCommand } from "./firewall.js";
|
||||
import { parsePasswd, parseSudoers } from "./users.js";
|
||||
import { buildHealthCheckCommand, parseHealthResult } from "./health.js";
|
||||
import { buildTailCommand, clampLines } from "./logs.js";
|
||||
} from "../../../hosts/managers/ssl.js";
|
||||
import {
|
||||
buildIptablesRuleCommand,
|
||||
buildNftRuleCommand,
|
||||
} 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", () => {
|
||||
it("single-quotes and escapes for the shell", () => {
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
resolveHostForSshConnect,
|
||||
resolveSshConnectConfigHost,
|
||||
shouldResolveBeforeSshConnect,
|
||||
} from "./ssh-dns.js";
|
||||
} from "../../hosts/ssh-dns.js";
|
||||
|
||||
describe("SSH DNS resolution", () => {
|
||||
it("retries transient EAI_AGAIN errors before returning an address", async () => {
|
||||
+1
-1
@@ -6,7 +6,7 @@ vi.mock("fs/promises", () => ({
|
||||
access: mockAccess,
|
||||
}));
|
||||
|
||||
import { resolveAgentSocket } from "./terminal-auth-helpers.js";
|
||||
import { resolveAgentSocket } from "../../hosts/terminal-auth-helpers.js";
|
||||
|
||||
describe("resolveAgentSocket", () => {
|
||||
const originalEnv = process.env.SSH_AUTH_SOCK;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { EventEmitter } from "events";
|
||||
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 {
|
||||
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 mockUpdateEnded = vi.fn().mockResolvedValue(undefined);
|
||||
|
||||
vi.mock("../database/db/index.js", () => ({
|
||||
vi.mock("../../database/db/index.js", () => ({
|
||||
getDb: () => ({}),
|
||||
}));
|
||||
|
||||
vi.mock("../database/repositories/factory.js", () => ({
|
||||
vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentSessionRecordingRepository: () => ({
|
||||
create: mockCreate,
|
||||
updateEnded: mockUpdateEnded,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("../utils/logger.js", () => ({
|
||||
vi.mock("../../utils/logger.js", () => ({
|
||||
sshLogger: {
|
||||
info: 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", () => {
|
||||
beforeEach(() => {
|
||||
@@ -1,7 +1,11 @@
|
||||
import { EventEmitter } from "node:events";
|
||||
import type { Client } from "ssh2";
|
||||
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", () => {
|
||||
it("adds common non-login shell tmux paths", () => {
|
||||
+1
-1
@@ -9,7 +9,7 @@ import {
|
||||
buildPaneMetrics,
|
||||
attachPanesToWindows,
|
||||
shellEscape,
|
||||
} from "./tmux-monitor-helpers.js";
|
||||
} from "../../hosts/tmux-monitor-helpers.js";
|
||||
|
||||
function join(...fields: (string | number)[]): string {
|
||||
return fields.join(SEP);
|
||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
||||
completeVaultOidc,
|
||||
signWithVault,
|
||||
type VaultProfileConfig,
|
||||
} from "./vault-signer-core.js";
|
||||
} from "../../hosts/vault-signer-core.js";
|
||||
|
||||
const { utils: ssh2Utils } = ssh2Pkg;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { toFixedNum, kibToGiB } from "./common-utils.js";
|
||||
import { toFixedNum, kibToGiB } from "../../../hosts/widgets/common-utils.js";
|
||||
|
||||
describe("toFixedNum", () => {
|
||||
it("rounds to the requested digit count", () => {
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { parseCpuLine } from "./cpu-collector.js";
|
||||
import { parseCpuLine } from "../../../hosts/widgets/cpu-collector.js";
|
||||
|
||||
describe("parseCpuLine", () => {
|
||||
it("parses a standard /proc/stat cpu line", () => {
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
parseSensorsOutput,
|
||||
parseSysfsThermalOutput,
|
||||
} from "./temperature-collector.js";
|
||||
} from "../../../hosts/widgets/temperature-collector.js";
|
||||
|
||||
describe("temperature collectors", () => {
|
||||
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);
|
||||
|
||||
vi.mock("../database/repositories/factory.js", () => ({
|
||||
vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentAuditLogRepository: vi.fn(() => ({
|
||||
create: createMock,
|
||||
})),
|
||||
}));
|
||||
|
||||
import { logAudit, getRequestMeta } from "./audit-logger.js";
|
||||
import { logAudit, getRequestMeta } from "../../utils/audit-logger.js";
|
||||
|
||||
describe("logAudit", () => {
|
||||
beforeEach(() => {
|
||||
+6
-6
@@ -11,7 +11,7 @@ const mocks = vi.hoisted(() => ({
|
||||
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 { drizzle } = await import("drizzle-orm/better-sqlite3");
|
||||
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: {
|
||||
getInstance: () => ({
|
||||
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: () => ({}) },
|
||||
}));
|
||||
|
||||
vi.mock("./data-crypto.js", () => ({
|
||||
vi.mock("../../utils/data-crypto.js", () => ({
|
||||
DataCrypto: { getInstance: () => ({}) },
|
||||
}));
|
||||
|
||||
vi.mock("./logger.js", () => ({
|
||||
vi.mock("../../utils/logger.js", () => ({
|
||||
authLogger: {
|
||||
debug: 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();
|
||||
|
||||
type SessionInput = {
|
||||
+6
-6
@@ -10,13 +10,13 @@ const mocks = vi.hoisted(() => ({
|
||||
adoptRecoveredDEK: vi.fn(async () => {}),
|
||||
}));
|
||||
|
||||
vi.mock("../database/db/index.js", () => ({
|
||||
vi.mock("../../database/db/index.js", () => ({
|
||||
db: {},
|
||||
getDb: () => ({}),
|
||||
saveMemoryDatabaseToFile: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../database/repositories/factory.js", () => ({
|
||||
vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentSettingsRepository: () => ({ get: async () => null }),
|
||||
createCurrentSessionRepository: () => ({}),
|
||||
createCurrentUserRepository: () => ({}),
|
||||
@@ -25,7 +25,7 @@ vi.mock("../database/repositories/factory.js", () => ({
|
||||
getCurrentSettingValue: () => null,
|
||||
}));
|
||||
|
||||
vi.mock("./user-keys.js", () => ({
|
||||
vi.mock("../../utils/user-keys.js", () => ({
|
||||
UserKeyManager: {
|
||||
getInstance: () => ({
|
||||
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,
|
||||
migratePasswordUserAtLogin: vi.fn(async () => true),
|
||||
}));
|
||||
|
||||
vi.mock("./system-crypto.js", () => ({
|
||||
vi.mock("../../utils/system-crypto.js", () => ({
|
||||
SystemCrypto: {
|
||||
getInstance: () => ({
|
||||
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();
|
||||
|
||||
function makeLegacyDataKeyWrap(
|
||||
+4
-4
@@ -4,7 +4,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
const settingsStore = new Map<string, 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,
|
||||
createCurrentSettingsRepository: () => ({
|
||||
upsert: async (key: string, value: string) => {
|
||||
@@ -24,7 +24,7 @@ vi.mock("../../database/repositories/factory.js", () => ({
|
||||
|
||||
const masterKey = crypto.randomBytes(32);
|
||||
|
||||
vi.mock("../system-crypto.js", () => ({
|
||||
vi.mock("../../../utils/system-crypto.js", () => ({
|
||||
SystemCrypto: {
|
||||
getInstance: () => ({
|
||||
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 {
|
||||
adoptRecoveredDEK,
|
||||
legacySettingsKeys,
|
||||
migratePasswordUserAtLogin,
|
||||
runBootDekMigration,
|
||||
} from "./dek-migration.js";
|
||||
} from "../../../utils/crypto-migration/dek-migration.js";
|
||||
|
||||
const manager = UserKeyManager.getInstance();
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -7,7 +7,7 @@ import {
|
||||
DATABASE_LAYER_PREUPGRADE_BACKUP_PREFIX,
|
||||
DATABASE_LAYER_SKIP_PREUPGRADE_BACKUP_ENV,
|
||||
ensureDatabaseLayerPreupgradeBackup,
|
||||
} from "./database-layer-preupgrade-backup.js";
|
||||
} from "../../utils/database-layer-preupgrade-backup.js";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
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", () => {
|
||||
afterEach(() => {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import crypto from "crypto";
|
||||
import { FieldCrypto } from "./field-crypto.js";
|
||||
import { FieldCrypto } from "../../utils/field-crypto.js";
|
||||
|
||||
const masterKey = crypto.randomBytes(32);
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
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", () => {
|
||||
let tempDir: string | null = null;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
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
|
||||
// and resets them to stay isolated.
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
getDesktopOidcCallbackUrl,
|
||||
isOidcTokenCallback,
|
||||
} from "./oidc-desktop-callback";
|
||||
} from "../../utils/oidc-desktop-callback.js";
|
||||
|
||||
describe("getDesktopOidcCallbackUrl", () => {
|
||||
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
|
||||
// database / encryption stack. We then drive hasPermission via a spied
|
||||
// getUserPermissions so we test the wildcard-matching logic in isolation.
|
||||
vi.mock("../database/db/index.js", () => ({ db: {} }));
|
||||
vi.mock("./logger.js", () => ({
|
||||
vi.mock("../../database/db/index.js", () => ({ db: {} }));
|
||||
vi.mock("../../utils/logger.js", () => ({
|
||||
databaseLogger: {
|
||||
debug: 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<
|
||||
typeof PermissionManager.getInstance
|
||||
+1
-1
@@ -5,7 +5,7 @@ import {
|
||||
getRequestBaseUrlWithForceHTTPS,
|
||||
getRequestOrigin,
|
||||
normalizeBasePath,
|
||||
} from "./request-origin.js";
|
||||
} from "../../utils/request-origin.js";
|
||||
|
||||
function request(headers: Record<string, string | string[] | undefined>) {
|
||||
return {
|
||||
+4
-4
@@ -9,7 +9,7 @@ const state = vi.hoisted(() => ({
|
||||
ownerCredential: null as Record<string, unknown> | null,
|
||||
}));
|
||||
|
||||
vi.mock("../database/repositories/factory.js", () => ({
|
||||
vi.mock("../../database/repositories/factory.js", () => ({
|
||||
createCurrentCredentialRepository: () => ({
|
||||
findByIdForUser: async (_userId: string, _id: number) =>
|
||||
state.ownerCredential,
|
||||
@@ -38,7 +38,7 @@ vi.mock("../database/repositories/factory.js", () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("./data-crypto.js", () => ({
|
||||
vi.mock("../../utils/data-crypto.js", () => ({
|
||||
DataCrypto: {
|
||||
validateUserAccess: (userId: string) => {
|
||||
if (userId === "owner") return ownerDEK;
|
||||
@@ -51,8 +51,8 @@ vi.mock("./data-crypto.js", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
import { FieldCrypto } from "./field-crypto.js";
|
||||
import { SharedCredentialManager } from "./shared-credential-manager.js";
|
||||
import { FieldCrypto } from "../../utils/field-crypto.js";
|
||||
import { SharedCredentialManager } from "../../utils/shared-credential-manager.js";
|
||||
|
||||
const manager = SharedCredentialManager.getInstance();
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import {
|
||||
preparePrivateKeyForSSH2,
|
||||
getFriendlyKeyTypeName,
|
||||
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
|
||||
// access to anything and exists only so the ssh2 parsing path is exercised for
|
||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
||||
detectPlatform,
|
||||
parseUserAgent,
|
||||
generateDeviceFingerprint,
|
||||
} from "./user-agent-parser.js";
|
||||
} from "../../utils/user-agent-parser.js";
|
||||
|
||||
function reqWith(headers: Record<string, string>): Request {
|
||||
return { headers } as unknown as Request;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
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", () => {
|
||||
function createDb() {
|
||||
@@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
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,
|
||||
createCurrentSettingsRepository: () => ({
|
||||
upsert: async (key: string, value: string) => {
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
UserKeyManager,
|
||||
UserKeyUnavailableError,
|
||||
userDekSettingsKey,
|
||||
} from "./user-keys.js";
|
||||
} from "../../utils/user-keys.js";
|
||||
|
||||
const masterKey = crypto.randomBytes(32);
|
||||
const manager = UserKeyManager.getInstance();
|
||||
@@ -12,7 +12,11 @@ vi.mock("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", () => {
|
||||
it("accepts colon-separated MAC addresses", () => {
|
||||
Reference in New Issue
Block a user