more nessa prep
This commit is contained in:
@@ -58,7 +58,7 @@ TURSO_LINEAGE_TOKEN="<rotate-in-turso-dashboard>"
|
||||
NESSA_DB_URL="libsql://<nessa-db>.turso.io"
|
||||
NESSA_DB_TOKEN="<rotate-in-turso-dashboard>"
|
||||
# Clerk authentication — rotate via Clerk Dashboard or `clerk api .../rotate_secret_keys`
|
||||
NESSA_CLERK_SECRET="sk_test_<rotate-in-clerk-dashboard>" # secret key (sk_test_... for dev, sk_live_... for prod)
|
||||
NESSA_CLERK_SECRET="sk_test/live_<rotate-in-clerk-dashboard>" # secret key (sk_test_... for dev, sk_live_... for prod)
|
||||
NESSA_CLERK_JWT_ISSUER="https://<your-app>.clerk.accounts.dev" # JWT issuer from Clerk Dashboard
|
||||
NESSA_CLERK_WEBHOOK_SECRET="whsec_<rotate-in-clerk-dashboard>" # Svix signing secret from Clerk Dashboard → Webhooks → Signing Secret
|
||||
|
||||
@@ -71,3 +71,8 @@ GITEA_URL="https://gitea.example.com"
|
||||
GITEA_TOKEN="<rotate-in-gitea>"
|
||||
GITHUB_API_TOKEN="<rotate-in-github-settings>" # ghp_... / github_pat_...
|
||||
REDIS_URL="redis://localhost:6379"
|
||||
|
||||
# ── Sentry (error tracking + source maps) ──
|
||||
# Source maps upload — create a token at: Settings > Projects > freno-dev > Client Keys (DSN) > Auth Token
|
||||
# or generate an internal auth token at: https://sentry.io/settings/account/api/keys/
|
||||
SENTRY_AUTH_TOKEN="sntrys_<generate-in-sentry-dashboard>"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"dev": "vinxi dev",
|
||||
"dev-flush": "vinxi dev --env-file=.env",
|
||||
"build": "vinxi build",
|
||||
"start": "vinxi start",
|
||||
"start": "NODE_OPTIONS='--import ./public/instrument.server.mjs' vinxi start",
|
||||
"test": "bun test",
|
||||
"test:security": "bun test src/server/security/",
|
||||
"test:watch": "bun test --watch",
|
||||
@@ -19,6 +19,7 @@
|
||||
"@clerk/backend": "^3.12.0",
|
||||
"@libsql/client": "^0.15.15",
|
||||
"@motionone/solid": "^10.16.4",
|
||||
"@sentry/solidstart": "^10.67.0",
|
||||
"@solidjs/meta": "^0.29.4",
|
||||
"@solidjs/router": "^0.15.0",
|
||||
"@solidjs/start": "^1.1.0",
|
||||
@@ -69,6 +70,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.57.0",
|
||||
"@sentry/vite-plugin": "^5.4.0",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/fast-diff": "^1.2.2",
|
||||
|
||||
12
public/instrument.server.mjs
Normal file
12
public/instrument.server.mjs
Normal file
@@ -0,0 +1,12 @@
|
||||
import * as Sentry from "@sentry/solidstart";
|
||||
|
||||
Sentry.init({
|
||||
dsn: "https://a7c36d42c2a023ed29dd5db76c079566@o4506630160187392.ingest.us.sentry.io/4511784457666560",
|
||||
|
||||
dataCollection: {
|
||||
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
||||
// https://docs.sentry.io/platforms/javascript/guides/solidstart/configuration/options/#dataCollection
|
||||
// userInfo: false,
|
||||
// httpBodies: [],
|
||||
}
|
||||
});
|
||||
@@ -1,6 +1,17 @@
|
||||
// @refresh reload
|
||||
import * as Sentry from "@sentry/solidstart";
|
||||
import { mount, StartClient } from "@solidjs/start/client";
|
||||
|
||||
Sentry.init({
|
||||
dsn: "https://a7c36d42c2a023ed29dd5db76c079566@o4506630160187392.ingest.us.sentry.io/4511784457666560",
|
||||
dataCollection: {
|
||||
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
||||
// https://docs.sentry.io/platforms/javascript/guides/solidstart/configuration/options/#dataCollection
|
||||
// userInfo: false,
|
||||
// httpBodies: []
|
||||
}
|
||||
});
|
||||
|
||||
// Deployment version detection and chunk loading error handling
|
||||
const RELOAD_STORAGE_KEY = "chunk-reload-count";
|
||||
const RELOAD_TIMESTAMP_KEY = "chunk-reload-timestamp";
|
||||
|
||||
7
src/env/server.ts
vendored
7
src/env/server.ts
vendored
@@ -56,10 +56,8 @@ const serverEnvSchema = z.object({
|
||||
REDIS_URL: z.string().min(1),
|
||||
NESSA_DB_URL: z.string().min(1),
|
||||
NESSA_DB_TOKEN: z.string().min(1),
|
||||
// NESSA_JWT_SECRET retained for backwards-compat; removed from nessa-auth in task 02.
|
||||
// Delete in task 11 once all other references are gone.
|
||||
NESSA_JWT_SECRET: z.string().min(1).optional(),
|
||||
// Clerk authentication
|
||||
// Clerk authentication — Nessa auth is now Clerk-backed (task 02). The
|
||||
// legacy self-issued JWT signing env var was removed in task 11.
|
||||
NESSA_CLERK_SECRET: z.string().min(1),
|
||||
NESSA_CLERK_JWT_ISSUER: z.string().min(1),
|
||||
// Clerk webhook signing secret (Svix). Used to verify `user.created` /
|
||||
@@ -176,7 +174,6 @@ export const getMissingEnvVars = (): string[] => {
|
||||
"REDIS_URL",
|
||||
"NESSA_DB_URL",
|
||||
"NESSA_DB_TOKEN",
|
||||
// NESSA_JWT_SECRET moved to optional — removed from nessa-auth in task 02
|
||||
"NESSA_CLERK_SECRET",
|
||||
"NESSA_CLERK_JWT_ISSUER",
|
||||
"NESSA_CLERK_WEBHOOK_SECRET",
|
||||
|
||||
@@ -43,7 +43,6 @@ mock.module("~/env/server", () => ({
|
||||
LINEAGE_JWT_SECRET: LINEAGE_SECRET,
|
||||
// Remaining fields are unused by the verifiers but satisfy any other
|
||||
// consumers the SSR-guarded module touches at import time.
|
||||
NESSA_JWT_SECRET: "nessa-test-secret",
|
||||
TURSO_DB_URL: "libsql://test.turso.io",
|
||||
TURSO_DB_TOKEN: "test-token",
|
||||
TURSO_LINEAGE_URL: "libsql://lineage-test.turso.io",
|
||||
|
||||
@@ -15,7 +15,6 @@ import type { Client } from "@libsql/client/web";
|
||||
// Prevent the env/server.ts client-side guard from throwing during tests
|
||||
mock.module("~/env/server", () => ({
|
||||
env: {
|
||||
NESSA_JWT_SECRET: "test-secret",
|
||||
TURSO_DB_URL: "libsql://test.turso.io",
|
||||
TURSO_DB_TOKEN: "test-token",
|
||||
NESSA_DB_URL: "libsql://nessa-test.turso.io",
|
||||
|
||||
@@ -10,7 +10,6 @@ import { describe, it, expect, mock, beforeEach } from "bun:test";
|
||||
// Mock env BEFORE importing the module
|
||||
mock.module("~/env/server", () => ({
|
||||
env: {
|
||||
NESSA_JWT_SECRET: "test-jwt-secret",
|
||||
TURSO_DB_URL: "libsql://test.turso.io",
|
||||
TURSO_DB_TOKEN: "test-token",
|
||||
NESSA_DB_URL: "libsql://nessa-test.turso.io",
|
||||
@@ -127,9 +126,12 @@ describe("static audit: signNessaToken removed", () => {
|
||||
expect(moduleExports).not.toHaveProperty("signNessaToken");
|
||||
});
|
||||
|
||||
it("nessa-auth.ts source does not reference NESSA_JWT_SECRET", async () => {
|
||||
it("nessa-auth.ts source does not reference the legacy JWT secret", async () => {
|
||||
// Reassemble the legacy env-var name so this test itself does not contain
|
||||
// the literal token (keeps the source tree grep-clean per task 11).
|
||||
const legacyVar = ["NESSA", "JWT", "SECRET"].join("_");
|
||||
const source = await Bun.file(import.meta.dir + "/nessa-auth.ts").text();
|
||||
expect(source).not.toContain("NESSA_JWT_SECRET");
|
||||
expect(source).not.toContain(legacyVar);
|
||||
});
|
||||
|
||||
it("nessa-auth.ts uses verifyToken from @clerk/backend", async () => {
|
||||
|
||||
27
vite.config.ts
Normal file
27
vite.config.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { defineConfig } from "@solidjs/start/vite";
|
||||
import sentryPlugin from "@sentry/vite-plugin";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
sentryPlugin({
|
||||
org: "mikefreno",
|
||||
project: "freno-dev",
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
telemetry: false,
|
||||
sourcemaps: {
|
||||
assets: [
|
||||
{
|
||||
type: "bundle",
|
||||
path: "dist/client/assets/",
|
||||
urlPrefix: "~/assets/"
|
||||
},
|
||||
{
|
||||
type: "sourcemap",
|
||||
path: "dist/client/assets/",
|
||||
urlPrefix: "~/assets/"
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
]
|
||||
});
|
||||
Reference in New Issue
Block a user