@@ -6,17 +6,17 @@ import {
66 type TimeStep ,
77 type TimeRange ,
88} from "./utils/container-health.ts" ;
9- import { restartContainer , getRestartCount } from "./utils/auto-restart.ts" ;
9+ import { restartContainer , stopContainer , getRestartCount , getStopCount , validateContainerName } from "./utils/auto-restart.ts" ;
1010import { getMonitorStatus , triggerHealthCheck } from "./health-monitor.ts" ;
1111import { checkJWT } from "./utils/jwt.ts" ;
1212
1313const TIME_RANGE_PRESETS : Record < TimeStep , TimeRange > = {
14- '1s' : { step : '1s' , duration : '5m' } ,
15- '15s' : { step : '15s' , duration : '15m' } ,
16- '1m' : { step : '1m' , duration : '1h' } ,
17- '5m' : { step : '5m' , duration : '6h' } ,
18- '1h' : { step : '1h' , duration : '24h' } ,
19- '1d' : { step : '1d' , duration : '7d' } ,
14+ '1s' : { step : '1s' , duration : '5m' } ,
15+ '15s' : { step : '15s' , duration : '15m' } ,
16+ '1m' : { step : '1m' , duration : '1h' } ,
17+ '5m' : { step : '5m' , duration : '6h' } ,
18+ '1h' : { step : '1h' , duration : '24h' } ,
19+ '1d' : { step : '1d' , duration : '7d' } ,
2020} ;
2121
2222
@@ -31,7 +31,7 @@ export async function getContainerHealth(ctx: Context): Promise<void> {
3131
3232 const summary = await getHealthSummary ( ) ;
3333
34- ctx . response . headers . set ( "Access-Control-Allow-Origin" , "*" ) ;
34+
3535 ctx . response . body = {
3636 total : summary . total ,
3737 healthy : summary . healthy ,
@@ -44,6 +44,7 @@ export async function getContainerHealth(ctx: Context): Promise<void> {
4444 memoryPercent : Math . round ( c . memoryPercent * 100 ) / 100 ,
4545 memoryUsageMB : Math . round ( c . memoryUsage / ( 1024 * 1024 ) ) ,
4646 restartCount : getRestartCount ( c . name ) ,
47+ stopCount : getStopCount ( c . name ) ,
4748 isHealthy : ! isUnhealthy ( c ) ,
4849 lastUpdated : c . lastUpdated . toISOString ( ) ,
4950 } ) ) ,
@@ -67,7 +68,7 @@ export async function getContainerMetrics(ctx: Context): Promise<void> {
6768
6869 const history = await getContainerHistory ( subdomain , range ) ;
6970
70- ctx . response . headers . set ( "Access-Control-Allow-Origin" , "*" ) ;
71+
7172 ctx . response . body = {
7273 subdomain,
7374 step : range . step ,
@@ -97,7 +98,7 @@ export async function getHealthDashboard(ctx: Context): Promise<void> {
9798 const summary = await getHealthSummary ( ) ;
9899 const monitorStatus = getMonitorStatus ( ) ;
99100
100- ctx . response . headers . set ( "Access-Control-Allow-Origin" , "*" ) ;
101+
101102 ctx . response . body = {
102103 overview : {
103104 total : summary . total ,
@@ -126,6 +127,55 @@ export async function getHealthDashboard(ctx: Context): Promise<void> {
126127
127128export async function restartContainerHandler ( ctx : Context ) : Promise < void > {
128129 const subdomain = ctx . params . subdomain ;
130+ let safeSubdomain = "" ;
131+ try {
132+ safeSubdomain = validateContainerName ( subdomain ) ;
133+ } catch {
134+ ctx . throw ( 400 , "Invalid container identifier" ) ;
135+ }
136+
137+ const body = await ctx . request . body ( ) . value ;
138+ let document ;
139+ try {
140+ document = typeof body === 'string' ? JSON . parse ( body ) : body ;
141+ } catch {
142+ document = body ;
143+ }
144+
145+ const author = document ?. author ;
146+ const token = document ?. token ;
147+ const provider = document ?. provider ;
148+
149+ if ( author !== await checkJWT ( provider , token ) ) {
150+ ctx . throw ( 401 ) ;
151+ }
152+
153+ try {
154+ await restartContainer ( safeSubdomain ) ;
155+
156+
157+ ctx . response . body = {
158+ status : "success" ,
159+ message : `Container ${ safeSubdomain } restart initiated` ,
160+ } ;
161+ } catch ( error ) {
162+ console . error ( `Failed to restart container ${ safeSubdomain } ` , error ) ;
163+ ctx . response . status = 500 ;
164+ ctx . response . body = {
165+ status : "error" ,
166+ message : `Failed to restart ${ safeSubdomain } ` ,
167+ } ;
168+ }
169+ }
170+
171+ export async function stopContainerHandler ( ctx : Context ) : Promise < void > {
172+ const subdomain = ctx . params . subdomain ;
173+ let safeSubdomain = "" ;
174+ try {
175+ safeSubdomain = validateContainerName ( subdomain ) ;
176+ } catch {
177+ ctx . throw ( 400 , "Invalid container identifier" ) ;
178+ }
129179
130180 const body = await ctx . request . body ( ) . value ;
131181 let document ;
@@ -144,18 +194,19 @@ export async function restartContainerHandler(ctx: Context): Promise<void> {
144194 }
145195
146196 try {
147- await restartContainer ( subdomain ) ;
197+ await stopContainer ( safeSubdomain ) ;
198+
148199
149- ctx . response . headers . set ( "Access-Control-Allow-Origin" , "*" ) ;
150200 ctx . response . body = {
151201 status : "success" ,
152- message : `Container ${ subdomain } restart initiated` ,
202+ message : `Container ${ safeSubdomain } stop initiated` ,
153203 } ;
154204 } catch ( error ) {
205+ console . error ( `Failed to stop container ${ safeSubdomain } ` , error ) ;
155206 ctx . response . status = 500 ;
156207 ctx . response . body = {
157208 status : "error" ,
158- message : `Failed to restart ${ subdomain } : ${ error } ` ,
209+ message : `Failed to stop ${ safeSubdomain } ` ,
159210 } ;
160211 }
161212}
@@ -181,7 +232,6 @@ export async function triggerHealthCheckHandler(ctx: Context): Promise<void> {
181232
182233 await triggerHealthCheck ( ) ;
183234
184- ctx . response . headers . set ( "Access-Control-Allow-Origin" , "*" ) ;
185235 ctx . response . body = {
186236 status : "success" ,
187237 message : "Health check triggered" ,
0 commit comments