Error
+{{ .error }}
+ Back toLogin +diff --git a/.editorconfig b/.editorconfig index 08d21b438..e78548245 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,3 +9,6 @@ indent_style = space indent_size = tab tab_width = 2 +[{go.mod,go.sum,*.go}] +indent_style = tab +indent_size = 4 diff --git a/example/main.go b/example/main.go index 1d798bcf2..0be509637 100644 --- a/example/main.go +++ b/example/main.go @@ -1,6 +1,8 @@ package main import ( + "encoding/json" + "fmt" "github.com/labstack/echo/v4" mw "github.com/labstack/echo/v4/middleware" "github.com/teamhanko/hanko/example/middleware" @@ -9,11 +11,12 @@ import ( "log" "net/http" "os" + "time" ) func main() { t := &Template{ - templates: template.Must(template.ParseGlob("public/html/index.html")), + templates: template.Must(template.ParseGlob("public/html/*.html")), } hankoUrl := getEnv("HANKO_URL") @@ -28,6 +31,7 @@ func main() { } e := echo.New() + e.Renderer = t e.Use(mw.LoggerWithConfig(mw.LoggerConfig{ Format: `{"time":"${time_rfc3339_nano}","time_unix":"${time_unix}","id":"${id}","remote_ip":"${remote_ip}",` + @@ -39,6 +43,8 @@ func main() { e.Use(middleware.CacheControlMiddleware()) e.Renderer = t + e.Static("/static", "public/assets") + e.GET("/", func(c echo.Context) error { indexData := IndexData{ HankoUrl: hankoUrl, @@ -46,8 +52,51 @@ func main() { } return c.Render(http.StatusOK, "index.html", &indexData) }) - e.File("/secured", "public/html/secured.html", middleware.SessionMiddleware(hankoUrlInternal)) + e.File("/unauthorized", "public/html/unauthorized.html") + e.GET("/secured", func(c echo.Context) error { + client := http.Client{} + req, err := http.NewRequest("GET", fmt.Sprintf("%s/users/%s", hankoUrlInternal, c.Get("user")), nil) + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Get("token"))) + if err != nil { + return c.Render(http.StatusOK, "error.html", map[string]interface{}{ + "error": err.Error(), + }) + } + + resp, err := client.Do(req) + if err != nil { + return c.Render(http.StatusOK, "error.html", map[string]interface{}{ + "error": err.Error(), + }) + } + + if resp != nil { + defer resp.Body.Close() + } + + user := struct { + ID string `json:"id"` + Email string `json:"email"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Verified bool `json:"verified"` + WebauthnCredentials []struct { + ID string `json:"id"` + } `json:"webauthn_credentials"` + }{} + err = json.NewDecoder(resp.Body).Decode(&user) + + if err != nil { + return c.Render(http.StatusOK, "error.html", map[string]interface{}{ + "error": err.Error(), + }) + } + + return c.Render(http.StatusOK, "secured.html", map[string]interface{}{ + "user": user.Email, + }) + }, middleware.SessionMiddleware(hankoUrlInternal)) e.GET("/logout", func(c echo.Context) error { cookie := &http.Cookie{ diff --git a/example/middleware/session.go b/example/middleware/session.go index 5f6a0adb3..752d371bc 100644 --- a/example/middleware/session.go +++ b/example/middleware/session.go @@ -31,6 +31,8 @@ func SessionMiddleware(hankoUrl string) echo.MiddlewareFunc { } log.Printf("session for user '%s' verified successfully", token.Subject()) + c.Set("token", cookie.Value) + c.Set("user", token.Subject()) return next(c) } diff --git a/example/public/assets/css/common.css b/example/public/assets/css/common.css new file mode 100644 index 000000000..f847aaa41 --- /dev/null +++ b/example/public/assets/css/common.css @@ -0,0 +1,47 @@ +@import url("fonts.css"); + +body { + margin: 0; + text-align: center; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background: url("../img/bg.png") no-repeat center center fixed; + background-size: cover; +} + +.main { + margin-top: 8rem; +} + +.footer { + margin-top: 6rem; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} + +.footer img{ + padding-bottom: 2.5rem; +} + +@media screen and (max-height: 667px) { + .main { + margin-top: 1rem; + } + .footer { + margin-top: 2rem; + } + .footer img { + padding-bottom: 1.5rem; + } +} + +@media screen and (max-width: 600px) { + .main { + padding: 0 1.25rem; + } +} diff --git a/example/public/assets/css/fonts.css b/example/public/assets/css/fonts.css new file mode 100644 index 000000000..56344e382 --- /dev/null +++ b/example/public/assets/css/fonts.css @@ -0,0 +1,39 @@ +/* inter-regular - latin */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url('../fonts/inter-v12-latin-regular.eot'); /* IE9 Compat Modes */ + src: local(''), + url('../fonts/inter-v12-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/inter-v12-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/inter-v12-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('../fonts/inter-v12-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('../fonts/inter-v12-latin-regular.svg#Inter') format('svg'); /* Legacy iOS */ +} +/* inter-500 - latin */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 500; + src: url('../fonts/inter-v12-latin-500.eot'); /* IE9 Compat Modes */ + src: local(''), + url('../fonts/inter-v12-latin-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/inter-v12-latin-500.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/inter-v12-latin-500.woff') format('woff'), /* Modern Browsers */ + url('../fonts/inter-v12-latin-500.ttf') format('truetype'), /* Safari, Android, iOS */ + url('../fonts/inter-v12-latin-500.svg#Inter') format('svg'); /* Legacy iOS */ +} +/* inter-600 - latin */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 600; + src: url('../fonts/inter-v12-latin-600.eot'); /* IE9 Compat Modes */ + src: local(''), + url('../fonts/inter-v12-latin-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/inter-v12-latin-600.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/inter-v12-latin-600.woff') format('woff'), /* Modern Browsers */ + url('../fonts/inter-v12-latin-600.ttf') format('truetype'), /* Safari, Android, iOS */ + url('../fonts/inter-v12-latin-600.svg#Inter') format('svg'); /* Legacy iOS */ +} diff --git a/example/public/assets/css/index.css b/example/public/assets/css/index.css new file mode 100644 index 000000000..6aa9efe19 --- /dev/null +++ b/example/public/assets/css/index.css @@ -0,0 +1,53 @@ +@import url("common.css"); + +hanko-auth { + --brand-color-h: 230; + --brand-color-s: 100%; + --brand-color-l: 90%; + + --font-family: "Inter", sans-serif; + --border-radius: 16px; + --input-height: 52px; +} + +hanko-auth::part(input) { + border-radius: 5px; + border-color: #BFC2CD; +} + +hanko-auth::part(container) { + margin: auto; + min-width: 300px; + max-width: 450px; + padding: 20px; +} + +hanko-auth::part(primary-button) { + background-color: #CBD4FF; + color: black; + border-style: none; + border-radius: 5px; + height: 52px; + font-weight: 500; +} + +hanko-auth::part(primary-button):hover { + background-color: #b3beff; +} + +hanko-auth::part(secondary-button) { + background-color: #506CF0; + color: white; + border-style: none; + border-radius: 5px; + height: 52px; + font-weight: 500; +} + +hanko-auth::part(secondary-button):hover { + background-color: #6980f2; +} + +hanko-auth::part(divider) { + border-bottom-color: #BFC2CD; +} diff --git a/example/public/assets/css/secured.css b/example/public/assets/css/secured.css new file mode 100644 index 000000000..fd122a9fe --- /dev/null +++ b/example/public/assets/css/secured.css @@ -0,0 +1,35 @@ +@import url("common.css"); + +.main { + color: white; +} + +.nav__itemList { + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; +} + +.nav__listItem { + float: right; +} + +.nav__link, +.nav__link:visited, +.nav__link:hover, +.nav__link:active { + display: block; + margin: 2.5rem; + color: white; + background-color: transparent; + text-decoration: none; +} + +.nav__link:hover { + text-decoration: underline; +} + +.profile { + min-height: 350px; +} diff --git a/example/public/assets/css/unauthorized.css b/example/public/assets/css/unauthorized.css new file mode 100644 index 000000000..1dd3c3074 --- /dev/null +++ b/example/public/assets/css/unauthorized.css @@ -0,0 +1,22 @@ +@import url("common.css"); + +.main { + color: white; +} + +a, +a:visited, +a:hover, +a:active { + display: block; + margin: 2.5rem; + color: white; + background-color: transparent; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + diff --git a/example/public/assets/fonts/inter-v12-latin-500.eot b/example/public/assets/fonts/inter-v12-latin-500.eot new file mode 100644 index 000000000..da2dac491 Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-500.eot differ diff --git a/example/public/assets/fonts/inter-v12-latin-500.svg b/example/public/assets/fonts/inter-v12-latin-500.svg new file mode 100644 index 000000000..77485eb6e --- /dev/null +++ b/example/public/assets/fonts/inter-v12-latin-500.svg @@ -0,0 +1,351 @@ + + + diff --git a/example/public/assets/fonts/inter-v12-latin-500.ttf b/example/public/assets/fonts/inter-v12-latin-500.ttf new file mode 100644 index 000000000..a5e8c6e43 Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-500.ttf differ diff --git a/example/public/assets/fonts/inter-v12-latin-500.woff b/example/public/assets/fonts/inter-v12-latin-500.woff new file mode 100644 index 000000000..19c7bf8f0 Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-500.woff differ diff --git a/example/public/assets/fonts/inter-v12-latin-500.woff2 b/example/public/assets/fonts/inter-v12-latin-500.woff2 new file mode 100644 index 000000000..6fc94ad0c Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-500.woff2 differ diff --git a/example/public/assets/fonts/inter-v12-latin-600.eot b/example/public/assets/fonts/inter-v12-latin-600.eot new file mode 100644 index 000000000..354be5ebc Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-600.eot differ diff --git a/example/public/assets/fonts/inter-v12-latin-600.svg b/example/public/assets/fonts/inter-v12-latin-600.svg new file mode 100644 index 000000000..e4095595e --- /dev/null +++ b/example/public/assets/fonts/inter-v12-latin-600.svg @@ -0,0 +1,351 @@ + + + diff --git a/example/public/assets/fonts/inter-v12-latin-600.ttf b/example/public/assets/fonts/inter-v12-latin-600.ttf new file mode 100644 index 000000000..8a800446c Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-600.ttf differ diff --git a/example/public/assets/fonts/inter-v12-latin-600.woff b/example/public/assets/fonts/inter-v12-latin-600.woff new file mode 100644 index 000000000..b606a875e Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-600.woff differ diff --git a/example/public/assets/fonts/inter-v12-latin-600.woff2 b/example/public/assets/fonts/inter-v12-latin-600.woff2 new file mode 100644 index 000000000..bc76d107f Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-600.woff2 differ diff --git a/example/public/assets/fonts/inter-v12-latin-regular.eot b/example/public/assets/fonts/inter-v12-latin-regular.eot new file mode 100644 index 000000000..cb419e997 Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-regular.eot differ diff --git a/example/public/assets/fonts/inter-v12-latin-regular.svg b/example/public/assets/fonts/inter-v12-latin-regular.svg new file mode 100644 index 000000000..5f5424444 --- /dev/null +++ b/example/public/assets/fonts/inter-v12-latin-regular.svg @@ -0,0 +1,351 @@ + + + diff --git a/example/public/assets/fonts/inter-v12-latin-regular.ttf b/example/public/assets/fonts/inter-v12-latin-regular.ttf new file mode 100644 index 000000000..179ee0cf7 Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-regular.ttf differ diff --git a/example/public/assets/fonts/inter-v12-latin-regular.woff b/example/public/assets/fonts/inter-v12-latin-regular.woff new file mode 100644 index 000000000..18662613f Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-regular.woff differ diff --git a/example/public/assets/fonts/inter-v12-latin-regular.woff2 b/example/public/assets/fonts/inter-v12-latin-regular.woff2 new file mode 100644 index 000000000..c659f5e4a Binary files /dev/null and b/example/public/assets/fonts/inter-v12-latin-regular.woff2 differ diff --git a/example/public/assets/img/bg.png b/example/public/assets/img/bg.png new file mode 100644 index 000000000..8a9fda591 Binary files /dev/null and b/example/public/assets/img/bg.png differ diff --git a/example/public/assets/img/exampleApp.svg b/example/public/assets/img/exampleApp.svg new file mode 100644 index 000000000..ccc62d165 --- /dev/null +++ b/example/public/assets/img/exampleApp.svg @@ -0,0 +1,3 @@ + diff --git a/example/public/assets/img/poweredBy.svg b/example/public/assets/img/poweredBy.svg new file mode 100644 index 000000000..7f7dcb048 --- /dev/null +++ b/example/public/assets/img/poweredBy.svg @@ -0,0 +1,12 @@ + diff --git a/example/public/html/error.html b/example/public/html/error.html new file mode 100644 index 000000000..fbfa176c4 --- /dev/null +++ b/example/public/html/error.html @@ -0,0 +1,20 @@ + + +
+ + +