Skip to content

Commit 67b0322

Browse files
committed
feat: jwt sign ok
1 parent 83621b8 commit 67b0322

2 files changed

Lines changed: 63 additions & 45 deletions

File tree

src/api.jwt.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Hono } from "hono";
2+
import { Context } from "hono";
3+
import { createJWT, JWTPayload } from "./api.admin.ts";
4+
5+
// Localhost-only middleware
6+
const localhostOnly = async (c: Context, next: () => Promise<void>) => {
7+
const clientIP = c.req.header("x-forwarded-for") || c.req.header("x-real-ip") || "127.0.0.1";
8+
const allowedIPs = ["127.0.0.1", "::1", "localhost"];
9+
10+
if (!allowedIPs.includes(clientIP)) {
11+
return c.json({ error: "Access denied. Only localhost is allowed." }, 403);
12+
}
13+
14+
await next();
15+
};
16+
17+
// Generate expiration time (24 hours from now)
18+
function generateExpiration(): number {
19+
const now = Math.floor(Date.now() / 1000);
20+
return now + (24 * 60 * 60); // 24 hours
21+
}
22+
23+
// Generate a default user ID
24+
function generateUserId(): string {
25+
return `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
26+
}
27+
28+
export function setupJWTRoutes() {
29+
const app = new Hono();
30+
31+
// Simple JWT creation - no parameters needed
32+
app.all("/create", localhostOnly, async (c: Context) => {
33+
try {
34+
const payload: JWTPayload = {
35+
sub: generateUserId(),
36+
exp: generateExpiration(),
37+
iat: Math.floor(Date.now() / 1000), // issued at
38+
type: "access",
39+
scope: "full",
40+
};
41+
42+
const token = await createJWT(payload);
43+
return c.json({
44+
token,
45+
payload,
46+
expires_in: 24 * 60 * 60, // 24 hours in seconds
47+
expires_at: new Date(payload.exp * 1000).toISOString(),
48+
}, 200);
49+
} catch (error) {
50+
console.error("JWT creation error:", error);
51+
return c.json({
52+
error: "Failed to create JWT",
53+
message: error instanceof Error ? error.message : String(error),
54+
}, 500);
55+
}
56+
});
57+
58+
return app;
59+
}

src/nanoedge.ts

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
stopAllServices,
1313
} from "./managers/service-manager.ts";
1414
import { setupApiRoutes, setupDocsRoutes } from "./api.service.ts";
15-
import { createJWT, JWTPayload, setupAdminAPIRoutes } from "./api.admin.ts";
15+
import { setupAdminAPIRoutes } from "./api.admin.ts";
16+
import { setupJWTRoutes } from "./api.jwt.ts";
1617
import { Context } from "hono";
1718
import openapi from "./openapi.ts";
1819
import { setupFunctionAPIRoutes } from "./api.function.ts";
@@ -31,18 +32,6 @@ export async function createNanoEdgeRT(
3132
app.use("*", cors());
3233
app.use("*", logger());
3334

34-
// Localhost-only middleware
35-
const localhostOnly = async (c: Context, next: () => Promise<void>) => {
36-
const clientIP = c.req.header("x-forwarded-for") || c.req.header("x-real-ip") || "127.0.0.1";
37-
const allowedIPs = ["127.0.0.1", "::1", "localhost"];
38-
39-
if (!allowedIPs.includes(clientIP)) {
40-
return c.json({ error: "Access denied. Only localhost is allowed." }, 403);
41-
}
42-
43-
await next();
44-
};
45-
4635
const status = (c: Context) => {
4736
const now = new Date();
4837
const upTimeMs = now.getTime() - new Date(startTime).getTime();
@@ -67,42 +56,12 @@ export async function createNanoEdgeRT(
6756
app.get("/status", status);
6857
app.get("/static/*", serveStatic({ root: "./" }));
6958

70-
// JWT creation API - localhost only
71-
app.post("/jwt/create", localhostOnly, async (c: Context) => {
72-
try {
73-
const body = await c.req.json();
74-
const { sub, exp, ...additionalClaims } = body;
75-
76-
if (!sub || !exp) {
77-
return c.json({
78-
error: "Missing required fields: 'sub' (subject) and 'exp' (expiration)",
79-
}, 400);
80-
}
81-
82-
const payload: JWTPayload = {
83-
sub,
84-
exp,
85-
...additionalClaims,
86-
};
87-
88-
const token = await createJWT(payload);
89-
return c.json({
90-
token,
91-
payload,
92-
}, 200);
93-
} catch (error) {
94-
console.error("JWT creation error:", error);
95-
return c.json({
96-
error: "Failed to create JWT",
97-
message: error instanceof Error ? error.message : String(error),
98-
}, 500);
99-
}
100-
});
101-
10259
app.route("/api/docs", setupDocsRoutes(serviceManagerState));
10360
app.route("/api/v2", setupApiRoutes(serviceManagerState));
10461
app.route("/functions/v2", setupFunctionAPIRoutes(dbContext));
10562
app.route("/admin-api/v2", setupAdminAPIRoutes(dbContext));
63+
app.route("/jwt", setupJWTRoutes());
64+
10665
const abortController = new AbortController();
10766
return [app, dbContext.config?.main_port || 8000, abortController, serviceManagerState];
10867
}

0 commit comments

Comments
 (0)