@@ -14,15 +14,15 @@ import type { Telemetry } from "./telemetry.ts";
1414// TODO: add a test for this.
1515
1616const LOCALSTACK_CONFIG_PROFILE_NAME = "profile localstack" ;
17- const VALID_ENDPOINT_URLS = [
18- "http:// localhost.localstack.cloud:4566" , // default
19- "http:// 127.0.0.1:4566 " ,
20- "http:// localhost:4566 " ,
17+ const VALID_HOSTNAMES = [
18+ "localhost.localstack.cloud" ,
19+ "127.0.0.1" ,
20+ "localhost" ,
2121] ;
22+ const DEFAULT_PORT = "4566" ;
2223const LOCALSTACK_CONFIG_PROPERTIES = {
2324 region : "us-east-1" ,
2425 output : "json" ,
25- endpoint_url : VALID_ENDPOINT_URLS ,
2626} ;
2727
2828// https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html
@@ -40,16 +40,30 @@ async function overrideSelection(
4040 override : boolean = false ,
4141) : Promise < OverrideDecision | undefined > {
4242 if ( override === true ) {
43- return "override " ;
43+ return "Override " ;
4444 }
4545 const fileList = filesToModify . join ( " and " ) ;
4646 const selection = await window . showWarningMessage (
4747 `The "localstack" AWS profile in ${ fileList } exists, but does not match the expected properties. Do you want to override it?` ,
48- "override " ,
48+ "Override " ,
4949 ) ;
5050 return selection ;
5151}
5252
53+ function isValidEndpointUrl ( url : string | undefined ) : boolean {
54+ if ( ! url ) return false ;
55+ try {
56+ const parsed = new URL ( url ) ;
57+ return (
58+ ( parsed . protocol === "http:" || parsed . protocol === "https:" ) &&
59+ VALID_HOSTNAMES . includes ( parsed . hostname ) &&
60+ parsed . port !== "" // port must be present
61+ ) ;
62+ } catch {
63+ return false ;
64+ }
65+ }
66+
5367function checkIfConfigNeedsOverride ( section : IniSection | undefined ) : boolean {
5468 if ( ! section ) {
5569 return true ; // profile doesn't exist
@@ -58,7 +72,7 @@ function checkIfConfigNeedsOverride(section: IniSection | undefined): boolean {
5872 return ! (
5973 section . properties . region &&
6074 section . properties . endpoint_url &&
61- VALID_ENDPOINT_URLS . includes ( section . properties . endpoint_url )
75+ isValidEndpointUrl ( section . properties . endpoint_url )
6276 ) ;
6377}
6478
@@ -93,7 +107,7 @@ async function dnsResolveCheck(): Promise<boolean> {
93107 }
94108}
95109
96- type OverrideDecision = "override " | "do_not_override" ;
110+ type OverrideDecision = "Override " | "do_not_override" ;
97111
98112async function configureAwsConfigProfile (
99113 awsConfigFilename : string ,
@@ -110,14 +124,14 @@ async function configureAwsConfigProfile(
110124 try {
111125 if ( section ) {
112126 // LocalStack profile exists, but does not match the expected properties
113- if ( overrideDecision === "override " ) {
127+ if ( overrideDecision === "Override " ) {
114128 // User chose to override the existing profile.
115129
116130 // check if dnsResolveCheck is successful
117131 const isDnsResolved = await dnsResolveCheck ( ) ;
118132 const endpointUrl = isDnsResolved
119- ? " http://localhost.localstack.cloud:4566"
120- : VALID_ENDPOINT_URLS [ 1 ] ;
133+ ? ` http://localhost.localstack.cloud:${ DEFAULT_PORT } `
134+ : `http://127.0.0.1: ${ DEFAULT_PORT } ` ;
121135
122136 const updatedIniFile = updateIniSection (
123137 iniFile ,
@@ -143,8 +157,8 @@ async function configureAwsConfigProfile(
143157 // check if dnsResolveCheck is successful
144158 const isDnsResolved = await dnsResolveCheck ( ) ;
145159 const endpointUrl = isDnsResolved
146- ? " http://localhost.localstack.cloud:4566"
147- : VALID_ENDPOINT_URLS [ 1 ] ;
160+ ? ` http://localhost.localstack.cloud:${ DEFAULT_PORT } `
161+ : `http://127.0.0.1: ${ DEFAULT_PORT } ` ;
148162
149163 const updatedIniFile = updateIniSection (
150164 iniFile ,
@@ -186,7 +200,7 @@ async function configureCredentialsProfile(
186200 try {
187201 // LocalStack profile exists, but does not match the expected properties
188202 if ( section ) {
189- if ( overrideDecision === "override " ) {
203+ if ( overrideDecision === "Override " ) {
190204 // User chose to override the existing profile.
191205 const updatedIniFile = updateIniSection (
192206 iniFile ,
@@ -321,7 +335,7 @@ export async function configureAwsProfiles(options: {
321335 // profiles are there but need adjustment
322336 // in testing, we always override
323337 if ( options ?. forceOverride ) {
324- overrideDecision = "override " ;
338+ overrideDecision = "Override " ;
325339 } else {
326340 // check which files need override
327341 const filesToModify = [ ] ;
@@ -333,7 +347,7 @@ export async function configureAwsProfiles(options: {
333347 }
334348 } else {
335349 // if any of the profiles don't exist, we need to create it
336- overrideDecision = "override " ;
350+ overrideDecision = "Override " ;
337351 }
338352
339353 if ( overrideDecision === undefined ) {
@@ -350,7 +364,7 @@ export async function configureAwsProfiles(options: {
350364 } ,
351365 } ) ;
352366 return ;
353- } else if ( overrideDecision === "override " ) {
367+ } else if ( overrideDecision === "Override " ) {
354368 if ( configNeedsOverride && credentialsNeedsOverride ) {
355369 [ configModified , credentialsModified ] = await Promise . all ( [
356370 configureAwsConfigProfile (
0 commit comments