Replace TS game shell with Bevy/Rust client, add auth service, purge legacy archive
- Replace apps/game (TypeScript/Vite/R3F) with a Bevy 0.16 Rust client featuring main menu, star map, and flight states - Add services/auth: Express + better-auth server with SpacetimeDB token exchange endpoint - Delete archive/legacy-static/ (old JS demos, CSS, assets) - Update docs pages (architecture, gameplay, roadmap, social, overview) to reflect Bevy pivot - Clean up workspace config: remove apps/game from pnpm workspace, update dev scripts, tsconfig, and AGENTS.md files - Add .vscode/settings.json for Rust tooling
This commit is contained in:
BIN
services/auth/auth.db
Normal file
BIN
services/auth/auth.db
Normal file
Binary file not shown.
24
services/auth/package.json
Normal file
24
services/auth/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "@void-nav/auth",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/index.ts",
|
||||
"start": "tsx src/index.ts",
|
||||
"migrate": "npx auth migrate"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-auth": "^1.2.0",
|
||||
"better-sqlite3": "^12.0.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"@types/cors": "^2.8.19",
|
||||
"@types/express": "^5.0.3",
|
||||
"tsx": "^4.19.4",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
38
services/auth/src/auth.ts
Normal file
38
services/auth/src/auth.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { betterAuth } from "better-auth";
|
||||
import Database from "better-sqlite3";
|
||||
import { jwt } from "better-auth/plugins";
|
||||
import { oidcProvider } from "better-auth/plugins";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: new Database("./auth.db"),
|
||||
baseURL: process.env.BETTER_AUTH_URL ?? "http://localhost:4000",
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
},
|
||||
session: {
|
||||
cookieCache: {
|
||||
enabled: true,
|
||||
maxAge: 60 * 5, // 5 minutes
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
jwt({
|
||||
// SpacetimeDB will verify JWTs via JWKS
|
||||
jwks: true,
|
||||
// Include standard OIDC claims that SpacetimeDB expects
|
||||
definePayload: async ({ session, user }) => ({
|
||||
sub: user.id,
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
}),
|
||||
}),
|
||||
oidcProvider({
|
||||
loginPage: "/sign-in",
|
||||
metadata: {
|
||||
issuer: process.env.BETTER_AUTH_URL ?? "http://localhost:4000",
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export type Auth = typeof auth;
|
||||
53
services/auth/src/index.ts
Normal file
53
services/auth/src/index.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import express from "express";
|
||||
import cors from "cors";
|
||||
import { toNodeHandler, fromNodeHeaders } from "better-auth/node";
|
||||
import { auth } from "./auth.js";
|
||||
|
||||
const app = express();
|
||||
const PORT = Number(process.env.AUTH_PORT ?? 4000);
|
||||
|
||||
app.use(
|
||||
cors({
|
||||
origin: [
|
||||
"http://localhost:5173",
|
||||
"http://localhost:5174",
|
||||
"http://localhost:5175",
|
||||
],
|
||||
credentials: true,
|
||||
}),
|
||||
);
|
||||
|
||||
// Mount better-auth handler FIRST — it handles /api/auth/*splat
|
||||
// Note: do NOT use express.json() before this handler
|
||||
app.all("/api/auth/*splat", toNodeHandler(auth));
|
||||
|
||||
// Mount json middleware only for routes below
|
||||
app.use(express.json());
|
||||
|
||||
// Token exchange endpoint: game client calls this with its session cookie
|
||||
// and receives a JWT suitable for SpacetimeDB
|
||||
app.get("/api/auth/spacetimedb-token", async (req, res) => {
|
||||
const session = await auth.api.getSession({
|
||||
headers: fromNodeHeaders(req.headers),
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
return res.status(401).json({ error: "Not authenticated" });
|
||||
}
|
||||
|
||||
// Get a JWT for this session
|
||||
const jwtResult = await auth.api.getToken({
|
||||
headers: fromNodeHeaders(req.headers),
|
||||
});
|
||||
|
||||
if (!jwtResult?.token) {
|
||||
return res.status(500).json({ error: "Failed to generate token" });
|
||||
}
|
||||
|
||||
return res.json({ token: jwtResult.token });
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`[auth] Auth server running on http://localhost:${PORT}`);
|
||||
console.log(`[auth] OIDC issuer: ${process.env.BETTER_AUTH_URL ?? `http://localhost:${PORT}`}`);
|
||||
});
|
||||
7
services/auth/tsconfig.json
Normal file
7
services/auth/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user