refactor: move gateway package to app directory

This commit is contained in:
Prad Nukala
2024-12-09 18:34:38 -05:00
parent 67432d3fdf
commit f250082fff
32 changed files with 13 additions and 13 deletions
+57
View File
@@ -0,0 +1,57 @@
package database
import (
"net/http"
"github.com/labstack/echo/v4"
"gorm.io/gorm"
)
var (
ErrInvalidCredentials = echo.NewHTTPError(http.StatusUnauthorized, "Invalid credentials")
ErrInvalidSubject = echo.NewHTTPError(http.StatusBadRequest, "Invalid subject")
ErrInvalidUser = echo.NewHTTPError(http.StatusBadRequest, "Invalid user")
ErrUserAlreadyExists = echo.NewHTTPError(http.StatusConflict, "User already exists")
ErrUserNotFound = echo.NewHTTPError(http.StatusNotFound, "User not found")
)
// Define the credential structure matching our frontend data
type Credential struct {
ID string `json:"id"`
RawID string `json:"rawId"`
Type string `json:"type"`
AuthenticatorAttachment string `json:"authenticatorAttachment"`
Transports []string `json:"transports"`
ClientExtensionResults map[string]interface{} `json:"clientExtensionResults"`
Response struct {
AttestationObject string `json:"attestationObject"`
ClientDataJSON string `json:"clientDataJSON"`
} `json:"response"`
}
type User struct {
gorm.Model
Address string `json:"address"`
Handle string `json:"handle"`
Name string `json:"name"`
CID string `json:"cid"`
Credentials []*Credential `json:"credentials"`
}
type Session struct {
gorm.Model
ID string `json:"id" gorm:"primaryKey"`
BrowserName string `json:"browserName"`
BrowserVersion string `json:"browserVersion"`
UserArchitecture string `json:"userArchitecture"`
Platform string `json:"platform"`
PlatformVersion string `json:"platformVersion"`
DeviceModel string `json:"deviceModel"`
UserHandle string `json:"userHandle"`
FirstName string `json:"firstName"`
LastInitial string `json:"lastInitial"`
VaultAddress string `json:"vaultAddress"`
HumanSum int `json:"humanSum"`
Challenge string `json:"challenge"`
}
+43
View File
@@ -0,0 +1,43 @@
package database
import (
"os"
"path/filepath"
"github.com/onsonr/sonr/app/gateway/config"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// InitDB initializes and returns a configured database connection
func InitDB(env config.Env) (*gorm.DB, error) {
path := formatDBPath(env.GetSqliteFile())
db, err := gorm.Open(sqlite.Open(path), &gorm.Config{})
if err != nil {
return nil, err
}
// Migrate the schema
db.AutoMigrate(&Session{})
db.AutoMigrate(&User{})
return db, nil
}
func formatDBPath(path string) string {
home := os.Getenv("HOME")
if home == "" {
home = os.Getenv("USERPROFILE")
}
if home == "" {
home = "."
}
configDir := filepath.Join(home, ".config", "hway")
if err := os.MkdirAll(configDir, 0o755); err != nil {
// If we can't create the directory, fall back to current directory
return path
}
return filepath.Join(configDir, path)
}
@@ -0,0 +1,29 @@
package index
import "github.com/onsonr/sonr/pkg/common/styles/layout"
templ NoWebauthnErrorView() {
@layout.Root("Error | Sonr.ID") {
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
<div class="relative flex flex-wrap items-center w-full h-full px-8">
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
<div class="flex flex-col items-center justify-center h-full">
<div class="flex flex-col items-center justify-center h-full">
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
No WebAuthn Devices
</h1>
<p class="text-lg text-zinc-500">
You don't have any WebAuthn devices connected to your computer.
</p>
</div>
<div class="flex flex-col items-center justify-center h-full">
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
Get Started
</button>
</div>
</div>
</div>
</div>
</div>
}
}
@@ -0,0 +1,60 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package index
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "github.com/onsonr/sonr/pkg/common/styles/layout"
func NoWebauthnErrorView() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">No WebAuthn Devices</h1><p class=\"text-lg text-zinc-500\">You don't have any WebAuthn devices connected to your computer.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Root("Error | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
@@ -0,0 +1,36 @@
package index
import (
"github.com/onsonr/sonr/pkg/common/styles/layout"
"github.com/onsonr/sonr/pkg/common/styles/text"
)
templ InitialView() {
@layout.Root("Sonr.ID") {
@layout.Container() {
@text.Header("Sonr.ID", "The decentralized identity layer for the web.")
<div class="pt-3 flex flex-col items-center justify-center h-full">
<sl-button hx-target="#container" hx-get="/register" hx-push-url="/register" type="button">
<sl-icon slot="prefix" library="sonr" name="sonr"></sl-icon>
Get Started
<sl-icon slot="suffix" library="sonr" name="arrow-right"></sl-icon>
</sl-button>
</div>
}
}
}
templ ReturningView() {
@layout.Root("Login | Sonr.ID") {
@layout.Container() {
@text.Header("Welcome Back!", "Continue with your existing Sonr.ID.")
<div class="pt-3 flex flex-col items-center justify-center h-full">
<sl-button hx-target="#container" hx-get="/register" type="button">
<sl-icon slot="prefix" library="sonr" name="sonr"></sl-icon>
Log back in
<sl-icon slot="suffix" library="sonr" name="arrow-right"></sl-icon>
</sl-button>
</div>
}
}
}
@@ -0,0 +1,154 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package index
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"github.com/onsonr/sonr/pkg/common/styles/layout"
"github.com/onsonr/sonr/pkg/common/styles/text"
)
func InitialView() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = text.Header("Sonr.ID", "The decentralized identity layer for the web.").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-3 flex flex-col items-center justify-center h-full\"><sl-button hx-target=\"#container\" hx-get=\"/register\" hx-push-url=\"/register\" type=\"button\"><sl-icon slot=\"prefix\" library=\"sonr\" name=\"sonr\"></sl-icon> Get Started <sl-icon slot=\"suffix\" library=\"sonr\" name=\"arrow-right\"></sl-icon></sl-button></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func ReturningView() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = text.Header("Welcome Back!", "Continue with your existing Sonr.ID.").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-3 flex flex-col items-center justify-center h-full\"><sl-button hx-target=\"#container\" hx-get=\"/register\" type=\"button\"><sl-icon slot=\"prefix\" library=\"sonr\" name=\"sonr\"></sl-icon> Log back in <sl-icon slot=\"suffix\" library=\"sonr\" name=\"arrow-right\"></sl-icon></sl-button></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Root("Login | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
+24
View File
@@ -0,0 +1,24 @@
package login
type LoginRequest struct {
Subject string
Action string
Origin string
Status string
Ping string
BlockSpeed string
BlockHeight string
}
type PublicKeyCredentialRequestOptions struct {
Challenge string `json:"challenge"`
RpID string `json:"rpId"`
Timeout int `json:"timeout,omitempty"`
UserVerification string `json:"userVerification,omitempty"`
AllowCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"`
}
type CredentialDescriptor struct {
Type string `json:"type"`
ID string `json:"id"`
}
@@ -0,0 +1,20 @@
package register
import (
"github.com/a-h/templ"
"github.com/go-webauthn/webauthn/protocol"
)
type LinkCredentialRequest struct {
Platform string `json:"platform"`
Handle string `json:"handle"`
DeviceModel string `json:"deviceModel"`
Architecture string `json:"architecture"`
Address string `json:"address"`
RegisterOptions protocol.PublicKeyCredentialCreationOptions `json:"registerOptions"`
}
func (r LinkCredentialRequest) GetCredentialOptions() string {
opts, _ := templ.JSONString(r.RegisterOptions)
return opts
}
@@ -0,0 +1,33 @@
package register
import (
"github.com/onsonr/sonr/pkg/common/styles/forms"
"github.com/onsonr/sonr/pkg/common/styles/layout"
"github.com/onsonr/sonr/pkg/common/styles/text"
)
templ ProfileFormView(data forms.CreateProfileData) {
@layout.Root("New Profile | Sonr.ID") {
@layout.Container() {
@text.Header("Create a Profile", "Enter some basic information about yourself.")
@forms.CreateProfile("/register/start", "POST", data)
}
}
}
templ LinkCredentialView(data forms.RegisterPasskeyData) {
@layout.Root("Register | Sonr.ID") {
@layout.Container() {
@text.Header("Link a PassKey", "This will be used to login to your vault.")
@forms.RegisterPasskey("/register/finish", "POST", data)
}
}
}
templ LoadingVaultView() {
@layout.Root("Loading... | Sonr.ID") {
@layout.Container() {
@text.Header("Loading Vault", "This will be used to login to your vault.")
}
}
}
@@ -0,0 +1,228 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package register
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"github.com/onsonr/sonr/pkg/common/styles/forms"
"github.com/onsonr/sonr/pkg/common/styles/layout"
"github.com/onsonr/sonr/pkg/common/styles/text"
)
func ProfileFormView(data forms.CreateProfileData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = text.Header("Create a Profile", "Enter some basic information about yourself.").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = forms.CreateProfile("/register/start", "POST", data).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Root("New Profile | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func LinkCredentialView(data forms.RegisterPasskeyData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = text.Header("Link a PassKey", "This will be used to login to your vault.").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = forms.RegisterPasskey("/register/finish", "POST", data).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Root("Register | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func LoadingVaultView() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
if templ_7745c5c3_Var7 == nil {
templ_7745c5c3_Var7 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = text.Header("Loading Vault", "This will be used to login to your vault.").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var9), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = layout.Root("Loading... | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
+102
View File
@@ -0,0 +1,102 @@
package session
import (
"regexp"
"strings"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/app/gateway/internal/database"
"github.com/onsonr/sonr/pkg/common"
"github.com/segmentio/ksuid"
)
// InitSession initializes or loads an existing session
func (s *HTTPContext) InitSession() error {
sessionID := s.getOrCreateSessionID()
// Try to load existing session
var sess database.Session
result := s.db.Where("id = ?", sessionID).First(&sess)
if result.Error != nil {
// Create new session if not found
bn, bv, arch, plat, platVer, model := extractBrowserInfo(s.Context)
sess = database.Session{
ID: sessionID,
BrowserName: bn,
BrowserVersion: bv,
UserArchitecture: arch,
Platform: plat,
PlatformVersion: platVer,
DeviceModel: model,
}
if err := s.db.Create(&sess).Error; err != nil {
return err
}
}
s.sess = &sess
return nil
}
func (s *HTTPContext) getOrCreateSessionID() string {
if ok := common.CookieExists(s.Context, common.SessionID); !ok {
sessionID := ksuid.New().String()
common.WriteCookie(s.Context, common.SessionID, sessionID)
return sessionID
}
sessionID, err := common.ReadCookie(s.Context, common.SessionID)
if err != nil {
sessionID = ksuid.New().String()
common.WriteCookie(s.Context, common.SessionID, sessionID)
}
return sessionID
}
func extractBrowserInfo(c echo.Context) (string, string, string, string, string, string) {
// Extract all relevant headers
browserName := common.HeaderRead(c, common.UserAgent)
arch := common.HeaderRead(c, common.Architecture)
platform := common.HeaderRead(c, common.Platform)
platformVer := common.HeaderRead(c, common.PlatformVersion)
model := common.HeaderRead(c, common.Model)
fullVersionList := common.HeaderRead(c, common.FullVersionList)
// Default values if headers are empty
if browserName == "" {
browserName = "N/A"
}
if arch == "" {
arch = "unknown"
}
if platform == "" {
platform = "unknown"
}
if platformVer == "" {
platformVer = "unknown"
}
if model == "" {
model = "unknown"
}
// Extract browser version from full version list
version := "-1"
if fullVersionList != "" {
entries := strings.Split(strings.TrimSpace(fullVersionList), ",")
for _, entry := range entries {
entry = strings.TrimSpace(entry)
re := regexp.MustCompile(`"([^"]+)";v="([^"]+)"`)
matches := re.FindStringSubmatch(entry)
if len(matches) == 3 {
browserName = matches[1]
version = matches[2]
if browserName != "Not.A/Brand" &&
browserName != "Chromium" {
break
}
}
}
}
return browserName, version, arch, platform, platformVer, model
}
+1
View File
@@ -0,0 +1 @@
package session
@@ -0,0 +1,53 @@
package session
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/app/gateway/config"
"github.com/onsonr/sonr/app/gateway/internal/database"
"gorm.io/gorm"
)
// Middleware creates a new session middleware
func Middleware(db *gorm.DB, env config.Env) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cc := NewHTTPContext(c, db)
if err := cc.InitSession(); err != nil {
return err
}
return next(cc)
}
}
}
// HTTPContext is the context for HTTP endpoints.
type HTTPContext struct {
echo.Context
db *gorm.DB
sess *database.Session
env config.Env
}
// Get returns the HTTPContext from the echo context
func Get(c echo.Context) (*HTTPContext, error) {
ctx, ok := c.(*HTTPContext)
if !ok {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Session Context not found")
}
return ctx, nil
}
// NewHTTPContext creates a new session context
func NewHTTPContext(c echo.Context, db *gorm.DB) *HTTPContext {
return &HTTPContext{
Context: c,
db: db,
}
}
// Session returns the current session
func (s *HTTPContext) Session() *database.Session {
return s.sess
}
+168
View File
@@ -0,0 +1,168 @@
package session
import (
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/app/gateway/internal/database"
)
// ╭───────────────────────────────────────────────────────╮
// │ DB Setter Functions │
// ╰───────────────────────────────────────────────────────╯
// SetUserHandle sets the user handle in the session
func SetUserHandle(c echo.Context, handle string) error {
sess, err := Get(c)
if err != nil {
return err
}
sess.Session().UserHandle = handle
return sess.db.Save(sess.Session()).Error
}
// SetFirstName sets the first name in the session
func SetFirstName(c echo.Context, name string) error {
sess, err := Get(c)
if err != nil {
return err
}
sess.Session().FirstName = name
return sess.db.Save(sess.Session()).Error
}
// SetLastInitial sets the last initial in the session
func SetLastInitial(c echo.Context, initial string) error {
sess, err := Get(c)
if err != nil {
return err
}
sess.Session().LastInitial = initial
return sess.db.Save(sess.Session()).Error
}
// SetVaultAddress sets the vault address in the session
func SetVaultAddress(c echo.Context, address string) error {
sess, err := Get(c)
if err != nil {
return err
}
sess.Session().VaultAddress = address
return sess.db.Save(sess.Session()).Error
}
// ╭───────────────────────────────────────────────────────╮
// │ DB Getter Functions │
// ╰───────────────────────────────────────────────────────╯
// GetID returns the session ID
func GetID(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().ID, nil
}
// GetBrowserName returns the browser name
func GetBrowserName(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().BrowserName, nil
}
// GetBrowserVersion returns the browser version
func GetBrowserVersion(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().BrowserVersion, nil
}
// GetUserArchitecture returns the user architecture
func GetUserArchitecture(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().UserArchitecture, nil
}
// GetPlatform returns the platform
func GetPlatform(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().Platform, nil
}
// GetPlatformVersion returns the platform version
func GetPlatformVersion(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().PlatformVersion, nil
}
// GetDeviceModel returns the device model
func GetDeviceModel(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().DeviceModel, nil
}
// GetUserHandle returns the user handle
func GetUserHandle(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().UserHandle, nil
}
// GetFirstName returns the first name
func GetFirstName(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().FirstName, nil
}
// GetLastInitial returns the last initial
func GetLastInitial(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().LastInitial, nil
}
// GetVaultAddress returns the vault address
func GetVaultAddress(c echo.Context) (string, error) {
sess, err := Get(c)
if err != nil {
return "", err
}
return sess.Session().VaultAddress, nil
}
// HandleExists checks if a handle already exists in any session
func HandleExists(c echo.Context, handle string) (bool, error) {
sess, err := Get(c)
if err != nil {
return false, err
}
var count int64
if err := sess.db.Model(&database.Session{}).Where("user_handle = ?", handle).Count(&count).Error; err != nil {
return false, err
}
return count > 0, nil
}