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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions apps/server/src/auth/EnvironmentAuth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,26 @@ import { expect, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";

import type { ServerConfigShape } from "../config.ts";
import { ServerConfig } from "../config.ts";
import * as ServerConfig from "../config.ts";
import { SqlitePersistenceMemory } from "../persistence/Layers/Sqlite.ts";
import * as PairingGrantStore from "./PairingGrantStore.ts";
import * as EnvironmentAuth from "./EnvironmentAuth.ts";

import * as ServerSecretStore from "./ServerSecretStore.ts";

const makeServerConfigLayer = (overrides?: Partial<ServerConfigShape>) =>
const makeServerConfigLayer = (overrides?: Partial<ServerConfig.ServerConfig["Service"]>) =>
Layer.effect(
ServerConfig,
ServerConfig.ServerConfig,
Effect.gen(function* () {
const config = yield* ServerConfig;
const config = yield* ServerConfig.ServerConfig;
return {
...config,
...overrides,
} satisfies ServerConfigShape;
} satisfies ServerConfig.ServerConfig["Service"];
}),
).pipe(Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-auth-server-test-" })));

const makeEnvironmentAuthLayer = (overrides?: Partial<ServerConfigShape>) =>
const makeEnvironmentAuthLayer = (overrides?: Partial<ServerConfig.ServerConfig["Service"]>) =>
EnvironmentAuth.layer.pipe(
Layer.provide(SqlitePersistenceMemory),
Layer.provide(ServerSecretStore.layer),
Expand All @@ -33,13 +32,15 @@ const makeEnvironmentAuthLayer = (overrides?: Partial<ServerConfigShape>) =>

const makeCookieRequest = (
sessionToken: string,
): Parameters<EnvironmentAuth.EnvironmentAuthShape["authenticateHttpRequest"]>[0] =>
): Parameters<EnvironmentAuth.EnvironmentAuth["Service"]["authenticateHttpRequest"]>[0] =>
({
cookies: {
t3_session: sessionToken,
},
headers: {},
}) as unknown as Parameters<EnvironmentAuth.EnvironmentAuthShape["authenticateHttpRequest"]>[0];
}) as unknown as Parameters<
EnvironmentAuth.EnvironmentAuth["Service"]["authenticateHttpRequest"]
>[0];

const requestMetadata = {
deviceType: "desktop" as const,
Expand Down
13 changes: 6 additions & 7 deletions apps/server/src/auth/EnvironmentAuthAdmin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,30 @@ import { expect, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";

import type { ServerConfigShape } from "../config.ts";
import { ServerConfig } from "../config.ts";
import * as ServerConfig from "../config.ts";
import { SqlitePersistenceMemory } from "../persistence/Layers/Sqlite.ts";
import * as EnvironmentAuth from "./EnvironmentAuth.ts";
import * as ServerSecretStore from "./ServerSecretStore.ts";
import * as SessionStore from "./SessionStore.ts";

const makeServerConfigLayer = (
overrides?: Partial<Pick<ServerConfigShape, "desktopBootstrapToken">>,
overrides?: Partial<Pick<ServerConfig.ServerConfig["Service"], "desktopBootstrapToken">>,
) =>
Layer.effect(
ServerConfig,
ServerConfig.ServerConfig,
Effect.gen(function* () {
const config = yield* ServerConfig;
const config = yield* ServerConfig.ServerConfig;
return {
...config,
...overrides,
} satisfies ServerConfigShape;
} satisfies ServerConfig.ServerConfig["Service"];
}),
).pipe(
Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-auth-control-plane-test-" })),
);

const makeEnvironmentAuthLayer = (
overrides?: Partial<Pick<ServerConfigShape, "desktopBootstrapToken">>,
overrides?: Partial<Pick<ServerConfig.ServerConfig["Service"], "desktopBootstrapToken">>,
) =>
EnvironmentAuth.layer.pipe(
Layer.provideMerge(ServerSecretStore.layer),
Expand Down
13 changes: 7 additions & 6 deletions apps/server/src/auth/EnvironmentAuthPolicy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@ import { expect, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";

import type { ServerConfigShape } from "../config.ts";
import { ServerConfig } from "../config.ts";
import * as ServerConfig from "../config.ts";
import * as EnvironmentAuthPolicy from "./EnvironmentAuthPolicy.ts";

const makeEnvironmentAuthPolicyLayer = (overrides?: Partial<ServerConfigShape>) =>
const makeEnvironmentAuthPolicyLayer = (
overrides?: Partial<ServerConfig.ServerConfig["Service"]>,
) =>
EnvironmentAuthPolicy.layer.pipe(
Layer.provide(
Layer.effect(
ServerConfig,
ServerConfig.ServerConfig,
Effect.gen(function* () {
const config = yield* ServerConfig;
const config = yield* ServerConfig.ServerConfig;
return {
...config,
...overrides,
} satisfies ServerConfigShape;
} satisfies ServerConfig.ServerConfig["Service"];
}),
).pipe(
Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-auth-policy-test-" })),
Expand Down
13 changes: 6 additions & 7 deletions apps/server/src/auth/PairingGrantStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,28 @@ import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as TestClock from "effect/testing/TestClock";

import type { ServerConfigShape } from "../config.ts";
import { ServerConfig } from "../config.ts";
import * as ServerConfig from "../config.ts";
import { SqlitePersistenceMemory } from "../persistence/Layers/Sqlite.ts";
import * as PairingGrantStore from "./PairingGrantStore.ts";

const makeServerConfigLayer = (
overrides?: Partial<Pick<ServerConfigShape, "desktopBootstrapToken">>,
overrides?: Partial<Pick<ServerConfig.ServerConfig["Service"], "desktopBootstrapToken">>,
) =>
Layer.effect(
ServerConfig,
ServerConfig.ServerConfig,
Effect.gen(function* () {
const config = yield* ServerConfig;
const config = yield* ServerConfig.ServerConfig;
return {
...config,
...overrides,
} satisfies ServerConfigShape;
} satisfies ServerConfig.ServerConfig["Service"];
}),
).pipe(
Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-auth-bootstrap-test-" })),
);

const makePairingGrantStoreLayer = (
overrides?: Partial<Pick<ServerConfigShape, "desktopBootstrapToken">>,
overrides?: Partial<Pick<ServerConfig.ServerConfig["Service"], "desktopBootstrapToken">>,
) =>
PairingGrantStore.layer.pipe(
Layer.provide(SqlitePersistenceMemory),
Expand Down
17 changes: 8 additions & 9 deletions apps/server/src/auth/SessionStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,29 @@ import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as TestClock from "effect/testing/TestClock";

import type { ServerConfigShape } from "../config.ts";
import { ServerConfig } from "../config.ts";
import * as ServerConfig from "../config.ts";
import { PersistenceSqlError } from "../persistence/Errors.ts";
import { SqlitePersistenceMemory } from "../persistence/Layers/Sqlite.ts";
import { AuthSessionRepository } from "../persistence/Services/AuthSessions.ts";
import * as AuthSessions from "../persistence/Services/AuthSessions.ts";
import * as SessionStore from "./SessionStore.ts";
import * as ServerSecretStore from "./ServerSecretStore.ts";

const makeServerConfigLayer = (
overrides?: Partial<Pick<ServerConfigShape, "desktopBootstrapToken">>,
overrides?: Partial<Pick<ServerConfig.ServerConfig["Service"], "desktopBootstrapToken">>,
) =>
Layer.effect(
ServerConfig,
ServerConfig.ServerConfig,
Effect.gen(function* () {
const config = yield* ServerConfig;
const config = yield* ServerConfig.ServerConfig;
return {
...config,
...overrides,
} satisfies ServerConfigShape;
} satisfies ServerConfig.ServerConfig["Service"];
}),
).pipe(Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-auth-session-test-" })));

const makeSessionStoreLayer = (
overrides?: Partial<Pick<ServerConfigShape, "desktopBootstrapToken">>,
overrides?: Partial<Pick<ServerConfig.ServerConfig["Service"], "desktopBootstrapToken">>,
) =>
SessionStore.layer.pipe(
Layer.provide(SqlitePersistenceMemory),
Expand All @@ -41,7 +40,7 @@ const repositoryFailure = new PersistenceSqlError({
detail: "sqlite is unavailable",
});

const failingSessionLookupRepositoryLayer = Layer.succeed(AuthSessionRepository, {
const failingSessionLookupRepositoryLayer = Layer.succeed(AuthSessions.AuthSessionRepository, {
create: () => Effect.void,
getById: () => Effect.fail(repositoryFailure),
listActive: () => Effect.succeed([]),
Expand Down
25 changes: 11 additions & 14 deletions apps/server/src/bin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import * as TestConsole from "effect/testing/TestConsole";
import { Command } from "effect/unstable/cli";

import { cli, makeCli } from "./bin.ts";
import { deriveServerPaths, ServerConfig, type ServerConfigShape } from "./config.ts";
import { ProjectionSnapshotQuery } from "./orchestration/Services/ProjectionSnapshotQuery.ts";
import * as ServerConfig from "./config.ts";
import * as ProjectionSnapshotQuery from "./orchestration/Services/ProjectionSnapshotQuery.ts";
import { OrchestrationLayerLive } from "./orchestration/runtimeLayer.ts";
import { orchestrationHttpApiLayer } from "./orchestration/http.ts";
import { layerConfig as SqlitePersistenceLayerLive } from "./persistence/Layers/Sqlite.ts";
Expand Down Expand Up @@ -57,7 +57,7 @@ const captureStdout = <A, E, R>(effect: Effect.Effect<A, E, R>) =>

const makeCliTestServerConfig = (baseDir: string) =>
Effect.gen(function* () {
const derivedPaths = yield* deriveServerPaths(baseDir, undefined);
const derivedPaths = yield* ServerConfig.deriveServerPaths(baseDir, undefined);
return {
logLevel: "Info",
traceMinLevel: "Info",
Expand All @@ -84,26 +84,23 @@ const makeCliTestServerConfig = (baseDir: string) =>
logWebSocketEvents: false,
tailscaleServeEnabled: false,
tailscaleServePort: 443,
} satisfies ServerConfigShape;
} satisfies ServerConfig.ServerConfig["Service"];
});

const makeProjectPersistenceLayer = (config: ServerConfigShape) =>
const makeProjectPersistenceLayer = (config: ServerConfig.ServerConfig["Service"]) =>
Layer.mergeAll(
OrchestrationLayerLive.pipe(
Layer.provideMerge(RepositoryIdentityResolverLive),
Layer.provideMerge(SqlitePersistenceLayerLive),
),
WorkspacePathsLive,
).pipe(
Layer.provideMerge(NodeServices.layer),
Layer.provide(Layer.succeed(ServerConfig, config)),
);
).pipe(Layer.provideMerge(NodeServices.layer), Layer.provide(ServerConfig.layer(config)));

const readPersistedSnapshot = (baseDir: string) =>
Effect.gen(function* () {
const config = yield* makeCliTestServerConfig(baseDir);
return yield* Effect.gen(function* () {
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery.ProjectionSnapshotQuery;
return yield* projectionSnapshotQuery.getSnapshot();
}).pipe(Effect.provide(makeProjectPersistenceLayer(config)));
});
Expand Down Expand Up @@ -133,7 +130,7 @@ const withLiveProjectCliServer = <A, E, R>(baseDir: string, run: () => Effect.Ef
}),
),
Layer.provideMerge(NodeServices.layer),
Layer.provide(Layer.succeed(ServerConfig, config)),
Layer.provide(ServerConfig.layer(config)),
);

return yield* Effect.scoped(
Expand Down Expand Up @@ -238,7 +235,7 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => {
it.effect("logs in to headless connect without enabling access", () =>
Effect.gen(function* () {
const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-login-test-"));
const { secretsDir } = yield* deriveServerPaths(baseDir, undefined);
const { secretsDir } = yield* ServerConfig.deriveServerPaths(baseDir, undefined);
mkdirSync(secretsDir, { recursive: true });
writeFileSync(
join(secretsDir, "cloud-cli-oauth-token.bin"),
Expand Down Expand Up @@ -282,7 +279,7 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => {
it.effect("logs out of headless connect and removes the stored CLI authorization", () =>
Effect.gen(function* () {
const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-logout-test-"));
const { secretsDir } = yield* deriveServerPaths(baseDir, undefined);
const { secretsDir } = yield* ServerConfig.deriveServerPaths(baseDir, undefined);
const tokenPath = join(secretsDir, "cloud-cli-oauth-token.bin");
mkdirSync(secretsDir, { recursive: true });
writeFileSync(tokenPath, "invalid persisted token");
Expand Down Expand Up @@ -461,7 +458,7 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => {
"--base-dir",
baseDir,
]);
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery.ProjectionSnapshotQuery;
const readModel = yield* projectionSnapshotQuery.getSnapshot();
const addedProject = readModel.projects.find(
(project) => project.workspaceRoot === workspaceRoot && project.deletedAt === null,
Expand Down
6 changes: 3 additions & 3 deletions apps/server/src/cli/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
formatPairingCredentialList,
formatSessionList,
} from "../cliAuthFormat.ts";
import { ServerConfig } from "../config.ts";
import * as ServerConfig from "../config.ts";
import {
authLocationFlags,
type CliAuthLocationFlags,
Expand All @@ -28,7 +28,7 @@ import {

const runWithEnvironmentAuth = <A, E>(
flags: CliAuthLocationFlags,
run: (environmentAuth: EnvironmentAuth.EnvironmentAuthShape) => Effect.Effect<A, E>,
run: (environmentAuth: EnvironmentAuth.EnvironmentAuth["Service"]) => Effect.Effect<A, E>,
options?: {
readonly quietLogs?: boolean;
},
Expand All @@ -43,7 +43,7 @@ const runWithEnvironmentAuth = <A, E>(
}).pipe(
Effect.provide(
Layer.mergeAll(EnvironmentAuth.runtimeLayer).pipe(
Layer.provide(Layer.succeed(ServerConfig, config)),
Layer.provide(ServerConfig.layer(config)),
Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)),
),
),
Expand Down
Loading
Loading