Skip to content

Commit 2112cb9

Browse files
authoredOct 2, 2024··
Merge pull request #432 from supertokens/feat/normalise-dashboard-connection-url
feat: normalise dashboard connection url
2 parents 60e0dc2 + 4449b38 commit 2112cb9

File tree

4 files changed

+184
-2
lines changed

4 files changed

+184
-2
lines changed
 

‎CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [unreleased]
99

10+
## [0.25.1] - 2024-10-02
11+
12+
- Adds support for normalizing the connection URI's before returning them in dashboard GET response.
13+
1014
## [0.25.0] - 2024-09-25
1115

1216
### Changes

‎recipe/dashboard/api/implementation.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package api
1717

1818
import (
1919
"strconv"
20+
"strings"
2021

2122
"github.com/supertokens/supertokens-golang/recipe/dashboard/constants"
2223
"github.com/supertokens/supertokens-golang/recipe/dashboard/dashboardmodels"
@@ -45,7 +46,22 @@ func MakeAPIImplementation() dashboardmodels.APIInterface {
4546
if err != nil {
4647
return "", err
4748
}
48-
connectionURI := stInstance.SuperTokens.ConnectionURI
49+
50+
// We are splitting the passed URI here so that if multiple URI's are passed
51+
// separated by a colon, the first one is returned.
52+
connectionURIToNormalize := strings.Split(stInstance.SuperTokens.ConnectionURI, ";")[0]
53+
54+
// This normalizes the URI to make sure that it has things like protocol etc
55+
// injected into it before it is returned.
56+
var normalizationError error
57+
normalizedConnectionURI, normalizationError := supertokens.NewNormalisedURLDomain(connectionURIToNormalize)
58+
if normalizationError != nil {
59+
// In case of failures, we want to return a 500 here, mainly because that
60+
// is what we return if the connectionURI is invalid which is the case here
61+
// if normalization fails.
62+
return "", normalizationError
63+
}
64+
connectionURI := normalizedConnectionURI.GetAsStringDangerous()
4965

5066
normalizedDashboardPath, err := supertokens.NewNormalisedURLPath(constants.DashboardAPI)
5167
if err != nil {

‎recipe/dashboard/dashboardGet_test.go

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package dashboard
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"net/http"
7+
"net/http/httptest"
8+
"strings"
9+
"testing"
10+
11+
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
12+
13+
"github.com/stretchr/testify/assert"
14+
"github.com/supertokens/supertokens-golang/recipe/dashboard/dashboardmodels"
15+
"github.com/supertokens/supertokens-golang/supertokens"
16+
"github.com/supertokens/supertokens-golang/test/unittesting"
17+
)
18+
19+
func TestThatDashboardGetNormalizesConnectionURIWithoutHTTP(t *testing.T) {
20+
connectionURI := "http://localhost:8080"
21+
connectionURIWithoutProtocol := strings.Replace(connectionURI, "http://", "", -1)
22+
config := supertokens.TypeInput{
23+
OnSuperTokensAPIError: func(err error, req *http.Request, res http.ResponseWriter) {
24+
print(err)
25+
},
26+
Supertokens: &supertokens.ConnectionInfo{
27+
ConnectionURI: connectionURIWithoutProtocol,
28+
},
29+
AppInfo: supertokens.AppInfo{
30+
APIDomain: "api.supertokens.io",
31+
AppName: "SuperTokens",
32+
WebsiteDomain: "supertokens.io",
33+
},
34+
RecipeList: []supertokens.Recipe{
35+
emailpassword.Init(nil),
36+
Init(&dashboardmodels.TypeInput{
37+
ApiKey: "testapikey",
38+
}),
39+
},
40+
}
41+
42+
BeforeEach()
43+
unittesting.StartUpST("localhost", "8080")
44+
defer AfterEach()
45+
err := supertokens.Init(config)
46+
if err != nil {
47+
t.Error(err.Error())
48+
}
49+
50+
mux := http.NewServeMux()
51+
testServer := httptest.NewServer(supertokens.Middleware(mux))
52+
defer testServer.Close()
53+
54+
req, err := http.NewRequest(http.MethodGet, testServer.URL+"/auth/dashboard", strings.NewReader(`{}`))
55+
req.Header.Set("Authorization", "Bearer testapikey")
56+
res, err := http.DefaultClient.Do(req)
57+
assert.Equal(t, res.StatusCode, 200)
58+
59+
if err != nil {
60+
t.Error(err.Error())
61+
}
62+
63+
body, _ := io.ReadAll(res.Body)
64+
assert.True(t, strings.Contains(string(body), fmt.Sprintf("window.connectionURI = \"%s\"", connectionURI)))
65+
}
66+
67+
func TestThatDashboardGetNormalizesConnectionURIWithoutHTTPS(t *testing.T) {
68+
connectionURI := "https://try.supertokens.com"
69+
connectionURIWithoutProtocol := strings.Replace(connectionURI, "https://", "", -1)
70+
config := supertokens.TypeInput{
71+
OnSuperTokensAPIError: func(err error, req *http.Request, res http.ResponseWriter) {
72+
print(err)
73+
},
74+
Supertokens: &supertokens.ConnectionInfo{
75+
ConnectionURI: connectionURIWithoutProtocol,
76+
},
77+
AppInfo: supertokens.AppInfo{
78+
APIDomain: "api.supertokens.io",
79+
AppName: "SuperTokens",
80+
WebsiteDomain: "supertokens.io",
81+
},
82+
RecipeList: []supertokens.Recipe{
83+
emailpassword.Init(nil),
84+
Init(&dashboardmodels.TypeInput{
85+
ApiKey: "testapikey",
86+
}),
87+
},
88+
}
89+
90+
BeforeEach()
91+
unittesting.StartUpST("localhost", "8080")
92+
defer AfterEach()
93+
err := supertokens.Init(config)
94+
if err != nil {
95+
t.Error(err.Error())
96+
}
97+
98+
mux := http.NewServeMux()
99+
testServer := httptest.NewServer(supertokens.Middleware(mux))
100+
defer testServer.Close()
101+
102+
req, err := http.NewRequest(http.MethodGet, testServer.URL+"/auth/dashboard", strings.NewReader(`{}`))
103+
req.Header.Set("Authorization", "Bearer testapikey")
104+
res, err := http.DefaultClient.Do(req)
105+
assert.Equal(t, res.StatusCode, 200)
106+
107+
if err != nil {
108+
t.Error(err.Error())
109+
}
110+
111+
body, _ := io.ReadAll(res.Body)
112+
assert.True(t, strings.Contains(string(body), fmt.Sprintf("window.connectionURI = \"%s\"", connectionURI)))
113+
}
114+
115+
func TestThatDashboardGetReturnsFirstURIWhenMultipleArePassed(t *testing.T) {
116+
firstConnectionURI := "http://localhost:8080"
117+
secondConnectionURI := "https://try.supertokens.com"
118+
multiplConnectionURIs := fmt.Sprintf("%s;%s", firstConnectionURI, secondConnectionURI)
119+
config := supertokens.TypeInput{
120+
OnSuperTokensAPIError: func(err error, req *http.Request, res http.ResponseWriter) {
121+
print(err)
122+
},
123+
Supertokens: &supertokens.ConnectionInfo{
124+
ConnectionURI: multiplConnectionURIs,
125+
},
126+
AppInfo: supertokens.AppInfo{
127+
APIDomain: "api.supertokens.io",
128+
AppName: "SuperTokens",
129+
WebsiteDomain: "supertokens.io",
130+
},
131+
RecipeList: []supertokens.Recipe{
132+
emailpassword.Init(nil),
133+
Init(&dashboardmodels.TypeInput{
134+
ApiKey: "testapikey",
135+
}),
136+
},
137+
}
138+
139+
BeforeEach()
140+
unittesting.StartUpST("localhost", "8080")
141+
defer AfterEach()
142+
err := supertokens.Init(config)
143+
if err != nil {
144+
t.Error(err.Error())
145+
}
146+
147+
mux := http.NewServeMux()
148+
testServer := httptest.NewServer(supertokens.Middleware(mux))
149+
defer testServer.Close()
150+
151+
req, err := http.NewRequest(http.MethodGet, testServer.URL+"/auth/dashboard", strings.NewReader(`{}`))
152+
req.Header.Set("Authorization", "Bearer testapikey")
153+
res, err := http.DefaultClient.Do(req)
154+
assert.Equal(t, res.StatusCode, 200)
155+
156+
if err != nil {
157+
t.Error(err.Error())
158+
}
159+
160+
body, _ := io.ReadAll(res.Body)
161+
assert.True(t, strings.Contains(string(body), fmt.Sprintf("window.connectionURI = \"%s\"", firstConnectionURI)))
162+
}

‎supertokens/constants.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const (
2121
)
2222

2323
// VERSION current version of the lib
24-
const VERSION = "0.25.0"
24+
const VERSION = "0.25.1"
2525

2626
var (
2727
cdiSupported = []string{"3.1"}

0 commit comments

Comments
 (0)