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
11 changes: 0 additions & 11 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@ APP_SECRET= # Application secret (used for JWT signing)
# ── Database ───────────────────────────────────────────────────
DATABASE_URL= # PostgreSQL connection string (postgresql://user:pass@host:port/db)

# ── Frontend (exposed to browser via Vite) ──────────────────────
VITE_KIMI_AUTH_URL= # Kimi OAuth server URL (e.g. https://auth.kimi.com)
VITE_APP_ID= # OAuth application ID

# ── Backend (Auth) ─────────────────────────────────────────────
KIMI_AUTH_URL= # Kimi OAuth server URL (backend)
KIMI_OPEN_URL= # Kimi Open Platform URL (e.g. https://open.kimi.com)

# ── Admin Role ──────────────────────────────────────────────────
OWNER_UNION_ID= # Union ID of the app creator; this user gets role "admin" on first login

# ── Application URL ────────────────────────────────────────────
APP_URL=http://localhost:5173 # Frontend URL (used for CORS)

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ jobs:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/finaflow_test
APP_ID: test_app
APP_SECRET: test_secret_key_ci_pipeline_2025
KIMI_AUTH_URL: http://localhost:3000/auth
KIMI_OPEN_URL: http://localhost:3000/open

build:
runs-on: ubuntu-latest
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ Key configuration is documented in `.env.example`. Essential variables:
| `DATABASE_URL` | PostgreSQL connection string |
| `APP_ID` | Application identifier |
| `APP_SECRET` | JWT signing secret |
| `KIMI_AUTH_URL` | OAuth server URL |
| `BCRYPT_ROUNDS` | Password hashing cost factor |

## Contributing
Expand Down
71 changes: 0 additions & 71 deletions api/__tests__/oauth-context.test.ts

This file was deleted.

15 changes: 7 additions & 8 deletions api/auth-router.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// ABOUTME: tRPC router for authenticated user queries and session management (logout).
// ABOUTME: The me endpoint returns the current user; logout clears the auth cookie.
import * as cookie from "cookie";
import { Session } from "@contracts/constants";
import { getSessionCookieOptions } from "./lib/cookies";
import { createRouter, authedQuery } from "./middleware";

export const authRouter = createRouter({
me: authedQuery.query((opts) => opts.ctx.user),
logout: authedQuery.mutation(async ({ ctx }) => {
const opts = getSessionCookieOptions(ctx.req.headers);
ctx.resHeaders.append(
"set-cookie",
cookie.serialize(Session.cookieName, "", {
httpOnly: opts.httpOnly,
path: opts.path,
sameSite: opts.sameSite?.toLowerCase() as "lax" | "none",
secure: opts.secure,
cookie.serialize("finaflow_token", "", {
httpOnly: true,
path: "/",
sameSite: "lax",
secure: false,
maxAge: 0,
}),
);
Expand Down
6 changes: 2 additions & 4 deletions api/boot.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ABOUTME: Hono server bootstrap that wires up CORS, security, rate limiting, CSRF, and tRPC request handling.
// ABOUTME: Also schedules background jobs (trial lifecycle) and handles graceful shutdown.
import { Hono } from "hono";
import { cors } from "hono/cors";
import { bodyLimit } from "hono/body-limit";
Expand All @@ -6,8 +8,6 @@ import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "./router";
import { createContext } from "./context";
import { env } from "./lib/env";
import { createOAuthCallbackHandler } from "./kimi/auth";
import { Paths } from "@contracts/constants";
import { securityHeaders } from "./lib/security-headers";
import { csrfProtection } from "./lib/csrf";
import { apiLimiter, loginLimiter } from "./lib/rate-limit";
Expand Down Expand Up @@ -36,8 +36,6 @@ app.use("*", cors({ origin: resolveCorsOrigin, credentials: true }));
app.use("*", securityHeaders);
app.use(bodyLimit({ maxSize: 50 * 1024 * 1024 }));

app.get(Paths.oauthCallback, createOAuthCallbackHandler());

app.get("/health", async (c) => {
try {
await getDb().execute(sql`SELECT 1`);
Expand Down
28 changes: 4 additions & 24 deletions api/context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ABOUTME: Creates the tRPC context by authenticating requests via cookie JWT (finaflow_token) or Bearer token fallback.
// ABOUTME: Resolves user identity, business assignments, and partner allocation rights for authorisation downstream.
import type { FetchCreateContextFnOptions } from "@trpc/server/adapters/fetch";
import type { User } from "@db/schema";
import { authenticateRequest } from "./kimi/auth";
import { verifyLocalToken } from "./local-auth-router";
import { getDb } from "./queries/connection";
import { users, businesses, userBusinesses, partnerAllocations } from "@db/schema";
Expand Down Expand Up @@ -84,7 +85,7 @@ export async function createContext(
}
}
} catch {
// Cookie auth failed, try Bearer token fallback, then OAuth
// Cookie auth failed, try Bearer token fallback
}

// Try Bearer token fallback
Expand Down Expand Up @@ -118,28 +119,7 @@ export async function createContext(
}
}
} catch {
// Bearer auth failed, try OAuth
}

// Try OAuth (Kimi)
try {
const oauthUser = await authenticateRequest(opts.req.headers);
if (oauthUser) {
const db = getDb();
const junctions = await db.select().from(userBusinesses)
.where(and(eq(userBusinesses.userId, oauthUser.id), eq(userBusinesses.isActive, true)));
const bizIds = junctions.map(j => j.businessId);
let currentBusiness: typeof businesses.$inferSelect | null = null;
if (oauthUser.currentBusinessId) {
const biz = await db.select().from(businesses)
.where(and(eq(businesses.id, oauthUser.currentBusinessId), isNull(businesses.deletedAt))).limit(1);
currentBusiness = biz[0] ?? null;
}
const allocationAccess = await resolveAllocationAccess(oauthUser.id, currentBusiness?.id ?? null);
ctx.user = { ...oauthUser, currentBusiness, businessIds: bizIds, ...allocationAccess };
}
} catch {
// Authentication is optional
// Bearer auth failed
}

return ctx;
Expand Down
115 changes: 0 additions & 115 deletions api/kimi/auth.ts

This file was deleted.

30 changes: 0 additions & 30 deletions api/kimi/platform.ts

This file was deleted.

40 changes: 0 additions & 40 deletions api/kimi/session.ts

This file was deleted.

Loading
Loading