@@ -12,7 +12,7 @@ import {
1212 stopAllServices ,
1313} from "./managers/service-manager.ts" ;
1414import { setupApiRoutes , setupDocsRoutes } from "./api.service.ts" ;
15- import { setupAdminAPIRoutes } from "./api.admin.ts" ;
15+ import { createJWT , JWTPayload , setupAdminAPIRoutes } from "./api.admin.ts" ;
1616import { Context } from "hono" ;
1717import openapi from "./openapi.ts" ;
1818import { setupFunctionAPIRoutes } from "./api.function.ts" ;
@@ -31,6 +31,18 @@ export async function createNanoEdgeRT(
3131 app . use ( "*" , cors ( ) ) ;
3232 app . use ( "*" , logger ( ) ) ;
3333
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+
3446 const status = ( c : Context ) => {
3547 const now = new Date ( ) ;
3648 const upTimeMs = now . getTime ( ) - new Date ( startTime ) . getTime ( ) ;
@@ -50,10 +62,43 @@ export async function createNanoEdgeRT(
5062 } ) ;
5163 } ;
5264 app . use ( "/docs" , swaggerUI ( { url : "/openapi.json" } ) ) ;
53- app . get ( "/openapi.json" , ( c ) => c . json ( openapi , 200 ) ) ;
65+ app . get ( "/openapi.json" , ( c : Context ) => c . json ( openapi , 200 ) ) ;
5466 app . get ( "/health" , status ) ;
5567 app . get ( "/status" , status ) ;
5668 app . get ( "/static/*" , serveStatic ( { root : "./" } ) ) ;
69+
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+
57102 app . route ( "/api/docs" , setupDocsRoutes ( serviceManagerState ) ) ;
58103 app . route ( "/api/v2" , setupApiRoutes ( serviceManagerState ) ) ;
59104 app . route ( "/functions/v2" , setupFunctionAPIRoutes ( dbContext ) ) ;
0 commit comments