feature/1115 execute ucan token (#1177)

- **deps: remove tigerbeetle-go dependency**
- **refactor: remove unused landing page components and models**
- **feat: add pin and publish vault handlers**
- **refactor: move payment and credential services to webui browser
package**
- **refactor: remove unused credentials management components**
- **feat: add landing page components and middleware for credentials and
payments**
- **refactor: remove unused imports in vault config**
- **refactor: remove unused bank, DID, and DWN gRPC clients**
- **refactor: rename client files and improve code structure**
- **feat: add session middleware helpers and landing page components**
- **feat: add user profile registration flow**
- **feat: Implement WebAuthn registration flow**
- **feat: add error view for users without WebAuthn devices**
- **chore: update htmx to include extensions**
- **refactor: rename pin handler to claim handler and update routes**
- **chore: update import paths after moving UI components and styles**
- **fix: address potential server errors by handling and logging them
properly**
- **refactor: move vault config to gateway package and update related
dependencies**
- **style: simplify form styling and remove unnecessary components**
- **feat: improve UI design for registration flow**
- **feat: implement passkey-based authentication**
- **refactor: migrate registration forms to use reusable form
components**
- **refactor: remove tailwindcss setup and use CDN instead**
- **style: update submit button style to use outline variant**
- **refactor: refactor server and IPFS client, remove MPC encryption**
- **refactor: Abstract keyshare functionality and improve message
encoding**
- **refactor: improve keyset JSON marshaling and error handling**
- **feat: add support for digital signatures using MPC keys**
- **fix: Refactor MarshalJSON to use standard json.Marshal for Message
serialization**
- **fix: Encode messages before storing in keyshare structs**
- **style: update form input styles for improved user experience**
- **refactor: improve code structure in registration handlers**
- **refactor: consolidate signer middleware and IPFS interaction**
- **refactor: rename MPC signing and refresh protocol functions**
- **refactor: update hway configuration loading mechanism**
- **feat: integrate database support for sessions and users**
- **refactor: remove devnet infrastructure and simplify build process**
- **docs(guides): add Sonr DID module guide**
- **feat: integrate progress bar into registration form**
- **refactor: migrate WebAuthn dependencies to protocol package**
- **feat: enhance user registration with passkey integration and
improved form styling**
- **refactor: move gateway view handlers to internal pages package**
- **refactor: Move address package to MPC module**
- **feat: integrate turnstile for registration**
- **style: remove unnecessary size attribute from buttons**
- **refactor: rename cookie package to session/cookie**
- **refactor: remove unnecessary types.Session dependency**
- **refactor: rename pkg/core to pkg/chain**
- **refactor: simplify deployment process by removing testnet-specific
Taskfile and devbox configuration**
- **feat: add error redirect functionality and improve routes**
- **feat: implement custom error handling for gateway**
- **chore: update version number to 0.0.7 in template**
- **feat: add IPFS client implementation**
- **feat: Implement full IPFS client interface with comprehensive
methods**
- **refactor: improve IPFS client path handling**
- **refactor: Move UCAN middleware to controller package**
- **feat: add UCAN middleware to motr**
- **refactor: update libp2p dependency**
- **docs: add UCAN specification document**
- **refactor: move UCAN controller logic to common package**
- **refactor: rename exports.go to common.go**
- **feat: add UCAN token support**
- **refactor: migrate UCAN token parsing to dedicated package**
- **refactor: improve CometBFT and app config initialization**
- **refactor: improve deployment scripts and documentation**
- **feat: integrate IPFS and producer middleware**
- **refactor: rename agent directory to aider**
- **fix: correct libp2p import path**
- **refactor: remove redundant dependency**
- **cleanup: remove unnecessary test files**
- **refactor: move attention types to crypto/ucan package**
- **feat: expand capabilities and resource types for UCANs**
- **refactor: rename sonr.go to codec.go and update related imports**
- **feat: add IPFS-based token store**
- **feat: Implement IPFS-based token store with caching and UCAN
integration**
- **feat: Add dynamic attenuation constructor for UCAN presets**
- **fix: Handle missing or invalid attenuation data with
EmptyAttenuation**
- **fix: Update UCAN attenuation tests with correct capability types**
- **feat: integrate UCAN-based authorization into the producer
middleware**
- **refactor: remove unused dependency on go-ucan**
- **refactor: Move address handling logic to DID module**
- **feat: Add support for compressed and uncompressed Secp256k1 public
keys in didkey**
- **test: Add test for generating DID key from MPC keyshares**
- **feat: Add methods for extracting compressed and uncompressed public
keys in share types**
- **feat: Add BaseKeyshare struct with public key conversion methods**
- **refactor: Use compressed and uncompressed public keys in keyshare,
fix public key usage in tests and verification**
- **feat: add support for key generation policy type**
- **fix: correct typo in VaultPermissions constant**
- **refactor: move JWT related code to ucan package**
- **refactor: move UCAN JWT and source code to spec package**
This commit is contained in:
Prad Nukala
2024-12-05 20:36:58 -05:00
committed by GitHub
parent e62ec45e82
commit bd51342fdf
256 changed files with 10823 additions and 7096 deletions
+7
View File
@@ -0,0 +1,7 @@
package handlers
import "github.com/labstack/echo/v4"
func HandleConnect(c echo.Context) error {
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package handlers
import (
"net/http"
"github.com/labstack/echo/v4"
)
func HandleDash(c echo.Context) error {
return c.Render(http.StatusOK, "index.templ", nil)
}
+48
View File
@@ -0,0 +1,48 @@
package handlers
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/common/response"
"github.com/onsonr/sonr/pkg/vault/internal/pages/index"
"github.com/onsonr/sonr/pkg/vault/internal/session"
)
func HandleIndex(c echo.Context) error {
if isInitial(c) {
return response.TemplEcho(c, index.InitialView())
}
if isExpired(c) {
return response.TemplEcho(c, index.ReturningView())
}
return c.Render(http.StatusOK, "index.templ", nil)
}
// ╭─────────────────────────────────────────────────────────╮
// │ Utility Functions │
// ╰─────────────────────────────────────────────────────────╯
// Initial users have no authorization, user handle, or vault address
func isInitial(c echo.Context) bool {
noAuth := !session.HasAuthorization(c)
noUserHandle := !session.HasUserHandle(c)
noVaultAddress := !session.HasVaultAddress(c)
return noUserHandle && noVaultAddress && noAuth
}
// Expired users have either a user handle or vault address
func isExpired(c echo.Context) bool {
noAuth := !session.HasAuthorization(c)
hasUserHandle := session.HasUserHandle(c)
hasVaultAddress := session.HasVaultAddress(c)
return noAuth && hasUserHandle || noAuth && hasVaultAddress
}
// Returning users have a valid authorization, and either a user handle or vault address
func isReturning(c echo.Context) bool {
hasAuth := session.HasAuthorization(c)
hasUserHandle := session.HasUserHandle(c)
hasVaultAddress := session.HasVaultAddress(c)
return hasAuth && (hasUserHandle || hasVaultAddress)
}
-1
View File
@@ -1 +0,0 @@
package handlers
+93
View File
@@ -0,0 +1,93 @@
package handlers
//
// // Constants for supported payment methods
// const (
// MethodCard = "basic-card"
// MethodGooglePay = "https://google.com/pay"
// MethodApplePay = "https://apple.com/apple-pay"
// MethodSonrWallet = "https://sonr.id/wallet"
// )
//
// // InitiatePayment starts the payment request flow
// func InitiatePayment(c echo.Context, request PaymentRequest) error {
// return StartPayment(request).Render(c.Request().Context(), c.Response().Writer)
// }
//
// // Helper functions to create payment requests
// func NewBasicCardPayment(amount float64, currency string, label string) PaymentRequest {
// return PaymentRequest{
// MethodData: []PaymentMethodData{
// {
// SupportedMethods: MethodCard,
// Data: map[string]any{
// "supportedNetworks": []string{"visa", "mastercard"},
// "supportedTypes": []string{"credit", "debit"},
// },
// },
// },
// Details: PaymentDetails{
// Total: PaymentItem{
// Label: label,
// Amount: Money{
// Currency: currency,
// Value: formatAmount(amount),
// },
// },
// },
// Options: PaymentOptions{
// RequestPayerName: true,
// RequestPayerEmail: true,
// },
// }
// }
//
// // Example usage:
// func PaymentHandler(c echo.Context) error {
// request := NewBasicCardPayment(99.99, "USD", "Product Purchase")
//
// // Add display items
// request.Details.DisplayItems = []PaymentItem{
// {
// Label: "Product Price",
// Amount: Money{
// Currency: "USD",
// Value: "89.99",
// },
// },
// {
// Label: "Tax",
// Amount: Money{
// Currency: "USD",
// Value: "10.00",
// },
// },
// }
//
// // Add shipping options
// request.Details.ShippingOptions = []ShippingOption{
// {
// ID: "standard",
// Label: "Standard Shipping",
// Amount: Money{
// Currency: "USD",
// Value: "0.00",
// },
// Selected: true,
// },
// {
// ID: "express",
// Label: "Express Shipping",
// Amount: Money{
// Currency: "USD",
// Value: "10.00",
// },
// },
// }
//
// return InitiatePayment(c, request)
// }
//
// func formatAmount(amount float64) string {
// return fmt.Sprintf("%.2f", amount)
// }
@@ -0,0 +1,7 @@
package authorize
type AuthorizeRequest struct {
Subject string
Action string
Origin string
}
@@ -0,0 +1,7 @@
package authorize
type AuthorizeRequest struct {
Subject string
Action string
Origin string
}
@@ -0,0 +1,57 @@
package dash
import "github.com/onsonr/sonr/pkg/styles/layout"
templ ProfileView() {
@layout.Root("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">
Sonr.ID
</h1>
<p class="text-lg text-zinc-500">
The decentralized identity layer for the web.
</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>
{ children... }
</div>
</div>
</div>
}
}
templ FeedView() {
@layout.Root("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">
Welcome Back!
</h1>
<p class="text-lg text-zinc-500">
Continue with your existing Sonr.ID.
</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">
Login
</button>
</div>
</div>
{ children... }
</div>
</div>
</div>
}
}
@@ -0,0 +1,123 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package dash
//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/styles/layout"
func ProfileView() 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\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</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>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
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 FeedView() 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_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var4 := 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\">Welcome Back!</h1><p class=\"text-lg text-zinc-500\">Continue with your existing Sonr.ID.</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\">Login</button></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
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_Var4), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
@@ -0,0 +1,29 @@
package index
import "github.com/onsonr/sonr/pkg/styles/layout"
templ NoWebauthnErrorView() {
@layout.Root("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/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("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,25 @@
package internal
templ IntroView() {
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
<div class="relative text-center">
<div class="flex flex-col mb-6 space-y-2">
<span>
<wa-qr-code size="140" value="https://shoelace.style/"></wa-qr-code>
</span>
<h1 class="text-2xl lg:text-3xl font-bold pb-3">
<span>Shoelace</span>
</h1>
<p class="text-lg text-zinc-500">
A lightweight library for building accessible, high-performance UI components with
no dependencies.
</p>
</div>
<div class="max-w-xs mx-auto sm:max-w-none sm:inline-flex sm:justify-center space-y-4 sm:space-y-0 sm:space-x-4">
<button class="inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font font-medium text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
Get started
</button>
</div>
</div>
</div>
}
@@ -0,0 +1,40 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package internal
//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"
func IntroView() 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_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"relative text-center\"><div class=\"flex flex-col mb-6 space-y-2\"><span><wa-qr-code size=\"140\" value=\"https://shoelace.style/\"></wa-qr-code></span><h1 class=\"text-2xl lg:text-3xl font-bold pb-3\"><span>Shoelace</span></h1><p class=\"text-lg text-zinc-500\">A lightweight library for building accessible, high-performance UI components with no dependencies.</p></div><div class=\"max-w-xs mx-auto sm:max-w-none sm:inline-flex sm:justify-center space-y-4 sm:space-y-0 sm:space-x-4\"><button class=\"inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font font-medium text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900\">Get started</button></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
@@ -0,0 +1,25 @@
package internal
templ ProfileForm() {
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
<div class="relative text-center">
<div class="flex flex-col mb-6 space-y-2">
<span>
<wa-qr-code size="140" value="https://shoelace.style/"></wa-qr-code>
</span>
<h1 class="text-2xl lg:text-3xl font-bold pb-3">
<span>Shoelace</span>
</h1>
<p class="text-lg text-zinc-500">
A lightweight library for building accessible, high-performance UI components with
no dependencies.
</p>
</div>
<div class="max-w-xs mx-auto sm:max-w-none sm:inline-flex sm:justify-center space-y-4 sm:space-y-0 sm:space-x-4">
<button class="inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font-medium text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
Get started
</button>
</div>
</div>
</div>
}
@@ -0,0 +1,40 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package internal
//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"
func ProfileForm() 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_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"relative text-center\"><div class=\"flex flex-col mb-6 space-y-2\"><span><wa-qr-code size=\"140\" value=\"https://shoelace.style/\"></wa-qr-code></span><h1 class=\"text-2xl lg:text-3xl font-bold pb-3\"><span>Shoelace</span></h1><p class=\"text-lg text-zinc-500\">A lightweight library for building accessible, high-performance UI components with no dependencies.</p></div><div class=\"max-w-xs mx-auto sm:max-w-none sm:inline-flex sm:justify-center space-y-4 sm:space-y-0 sm:space-x-4\"><button class=\"inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font-medium text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900\">Get started</button></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
+57
View File
@@ -0,0 +1,57 @@
package index
import "github.com/onsonr/sonr/pkg/styles/layout"
templ InitialView() {
@layout.Root("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">
Sonr.ID
</h1>
<p class="text-lg text-zinc-500">
The decentralized identity layer for the web.
</p>
</div>
<br/>
<div class="pt-3 flex flex-col items-center justify-center h-full">
<div hx-get="/register" hx-swap="outerHTML" class="pointer:cursor-pointer btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
Get Started
</div>
</div>
</div>
</div>
</div>
</div>
}
}
templ ReturningView() {
@layout.Root("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">
Welcome Back!
</h1>
<p class="text-lg text-zinc-500">
Continue with your existing Sonr.ID.
</p>
</div>
<br/>
<div class="pt-3 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">
Login
</button>
</div>
</div>
</div>
</div>
</div>
}
}
@@ -0,0 +1,107 @@
// 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/styles/layout"
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_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\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</p></div><br><div class=\"pt-3 flex flex-col items-center justify-center h-full\"><div hx-get=\"/register\" hx-swap=\"outerHTML\" class=\"pointer:cursor-pointer btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</div></div></div></div></div></div>")
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_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var4 := 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\">Welcome Back!</h1><p class=\"text-lg text-zinc-500\">Continue with your existing Sonr.ID.</p></div><br><div class=\"pt-3 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\">Login</button></div></div></div></div></div>")
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_Var4), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
+43
View File
@@ -0,0 +1,43 @@
package wallet
// Payment types
type PaymentMethodData struct {
SupportedMethods string `json:"supportedMethods"`
Data map[string]any `json:"data,omitempty"`
}
type PaymentItem struct {
Label string `json:"label"`
Amount Money `json:"amount"`
}
type Money struct {
Currency string `json:"currency"`
Value string `json:"value"` // Decimal as string for precision
}
type PaymentOptions struct {
RequestPayerName bool `json:"requestPayerName,omitempty"`
RequestPayerEmail bool `json:"requestPayerEmail,omitempty"`
RequestPayerPhone bool `json:"requestPayerPhone,omitempty"`
RequestShipping bool `json:"requestShipping,omitempty"`
}
type PaymentDetails struct {
Total PaymentItem `json:"total"`
DisplayItems []PaymentItem `json:"displayItems,omitempty"`
ShippingOptions []ShippingOption `json:"shippingOptions,omitempty"`
}
type ShippingOption struct {
ID string `json:"id"`
Label string `json:"label"`
Amount Money `json:"amount"`
Selected bool `json:"selected,omitempty"`
}
type PaymentRequest struct {
MethodData []PaymentMethodData `json:"methodData"`
Details PaymentDetails `json:"details"`
Options PaymentOptions `json:"options,omitempty"`
}
+111
View File
@@ -0,0 +1,111 @@
package wallet
import "github.com/onsonr/sonr/pkg/styles/layout"
templ DepositFundsView() {
@layout.Root("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">
Sonr.ID
</h1>
<p class="text-lg text-zinc-500">
The decentralized identity layer for the web.
</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>
{ children... }
</div>
</div>
</div>
}
}
templ SwapTokensView() {
@layout.Root("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">
Sonr.ID
</h1>
<p class="text-lg text-zinc-500">
The decentralized identity layer for the web.
</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>
{ children... }
</div>
</div>
</div>
}
}
templ ConfirmPasscodeView() {
@layout.Root("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">
Sonr.ID
</h1>
<p class="text-lg text-zinc-500">
The decentralized identity layer for the web.
</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>
{ children... }
</div>
</div>
</div>
}
}
templ TransferTokensView() {
@layout.Root("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">
Welcome Back!
</h1>
<p class="text-lg text-zinc-500">
Continue with your existing Sonr.ID.
</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">
Login
</button>
</div>
</div>
{ children... }
</div>
</div>
</div>
}
}
@@ -0,0 +1,233 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package wallet
//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/styles/layout"
func DepositFundsView() 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\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</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>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
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 SwapTokensView() 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_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var4 := 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\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</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>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
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_Var4), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func ConfirmPasscodeView() 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_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(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 = 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\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</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>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
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_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func TransferTokensView() 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_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\">Welcome Back!</h1><p class=\"text-lg text-zinc-500\">Continue with your existing Sonr.ID.</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\">Login</button></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var7.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
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_Var8), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
@@ -0,0 +1,107 @@
package wallet
var paymentsHandle = templ.NewOnceHandle()
// Base payments script template
templ PaymentsScripts() {
@paymentsHandle.Once() {
<script type="text/javascript">
// Check if Payment Request API is supported
function isPaymentRequestSupported() {
return window.PaymentRequest !== undefined;
}
// Create and show payment request
async function showPaymentRequest(request) {
try {
const paymentMethods = request.methodData;
const details = request.details;
const options = request.options || {};
const paymentRequest = new PaymentRequest(
paymentMethods,
details,
options
);
// Handle shipping address changes if shipping is requested
if (options.requestShipping) {
paymentRequest.addEventListener('shippingaddresschange', event => {
event.updateWith(Promise.resolve(details));
});
}
// Handle shipping option changes
if (details.shippingOptions && details.shippingOptions.length > 0) {
paymentRequest.addEventListener('shippingoptionchange', event => {
event.updateWith(Promise.resolve(details));
});
}
const response = await paymentRequest.show();
// Create response object
const result = {
methodName: response.methodName,
details: response.details,
};
if (options.requestPayerName) {
result.payerName = response.payerName;
}
if (options.requestPayerEmail) {
result.payerEmail = response.payerEmail;
}
if (options.requestPayerPhone) {
result.payerPhone = response.payerPhone;
}
if (options.requestShipping) {
result.shippingAddress = response.shippingAddress;
result.shippingOption = response.shippingOption;
}
// Complete the payment
await response.complete('success');
// Dispatch success event
window.dispatchEvent(new CustomEvent('paymentComplete', {
detail: result
}));
} catch (err) {
// Dispatch error event
window.dispatchEvent(new CustomEvent('paymentError', {
detail: err.message
}));
}
}
// Abort payment request
function abortPaymentRequest() {
if (window.currentPaymentRequest) {
window.currentPaymentRequest.abort();
}
}
</script>
}
}
// StartPayment for initiating payment request
templ StartPayment(request PaymentRequest) {
@PaymentsScripts()
<script>
(async () => {
try {
if (!isPaymentRequestSupported()) {
throw new Error("Payment Request API is not supported in this browser");
}
const request = { templ.JSONString(request) };
await showPaymentRequest(request);
} catch (err) {
window.dispatchEvent(new CustomEvent('paymentError', {
detail: err.message
}));
}
})();
</script>
}
@@ -0,0 +1,95 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.793
package wallet
//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"
var paymentsHandle = templ.NewOnceHandle()
// Base payments script template
func PaymentsScripts() 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("<script type=\"text/javascript\">\n // Check if Payment Request API is supported\n function isPaymentRequestSupported() {\n return window.PaymentRequest !== undefined;\n }\n\n // Create and show payment request\n async function showPaymentRequest(request) {\n try {\n const paymentMethods = request.methodData;\n const details = request.details;\n const options = request.options || {};\n\n const paymentRequest = new PaymentRequest(\n paymentMethods,\n details,\n options\n );\n\n // Handle shipping address changes if shipping is requested\n if (options.requestShipping) {\n paymentRequest.addEventListener('shippingaddresschange', event => {\n event.updateWith(Promise.resolve(details));\n });\n }\n\n // Handle shipping option changes\n if (details.shippingOptions && details.shippingOptions.length > 0) {\n paymentRequest.addEventListener('shippingoptionchange', event => {\n event.updateWith(Promise.resolve(details));\n });\n }\n\n const response = await paymentRequest.show();\n \n // Create response object\n const result = {\n methodName: response.methodName,\n details: response.details,\n };\n\n if (options.requestPayerName) {\n result.payerName = response.payerName;\n }\n if (options.requestPayerEmail) {\n result.payerEmail = response.payerEmail;\n }\n if (options.requestPayerPhone) {\n result.payerPhone = response.payerPhone;\n }\n if (options.requestShipping) {\n result.shippingAddress = response.shippingAddress;\n result.shippingOption = response.shippingOption;\n }\n\n // Complete the payment\n await response.complete('success');\n\n // Dispatch success event\n window.dispatchEvent(new CustomEvent('paymentComplete', {\n detail: result\n }));\n\n } catch (err) {\n // Dispatch error event\n window.dispatchEvent(new CustomEvent('paymentError', {\n detail: err.message\n }));\n }\n }\n\n // Abort payment request\n function abortPaymentRequest() {\n if (window.currentPaymentRequest) {\n window.currentPaymentRequest.abort();\n }\n }\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = paymentsHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
// StartPayment for initiating payment request
func StartPayment(request PaymentRequest) 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_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = PaymentsScripts().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n (async () => {\n try {\n if (!isPaymentRequestSupported()) {\n throw new Error(\"Payment Request API is not supported in this browser\");\n }\n const request = { templ.JSONString(request) };\n await showPaymentRequest(request);\n } catch (err) {\n window.dispatchEvent(new CustomEvent('paymentError', {\n detail: err.message\n }));\n }\n })();\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate
+156
View File
@@ -0,0 +1,156 @@
package session
import (
"regexp"
"strings"
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/protocol/webauthncose"
"github.com/labstack/echo/v4"
"github.com/segmentio/ksuid"
"github.com/onsonr/sonr/pkg/common"
)
const kWebAuthnTimeout = 6000
// TODO: Returns fixed chain ID for testing.
func GetChainID(c echo.Context) string {
return "sonr-testnet-1"
}
// SetVaultAddress sets the address of the vault
func SetVaultAddress(c echo.Context, address string) error {
return common.WriteCookie(c, common.SonrAddress, address)
}
// SetVaultAuthorization sets the UCAN CID of the vault
func SetVaultAuthorization(c echo.Context, ucanCID string) error {
common.HeaderWrite(c, common.Authorization, formatAuth(ucanCID))
return nil
}
// ╭───────────────────────────────────────────────────────────╮
// │ Initialization │
// ╰───────────────────────────────────────────────────────────╯
func loadOrGenKsuid(c echo.Context) error {
var (
sessionID string
err error
)
// Setup genKsuid function
genKsuid := func() string {
return ksuid.New().String()
}
// Attempt to read the session ID from the "session" cookie
if ok := common.CookieExists(c, common.SessionID); !ok {
sessionID = genKsuid()
} else {
sessionID, err = common.ReadCookie(c, common.SessionID)
if err != nil {
sessionID = genKsuid()
}
}
common.WriteCookie(c, common.SessionID, sessionID)
return nil
}
// ╭───────────────────────────────────────────────────────────╮
// │ Extraction │
// ╰───────────────────────────────────────────────────────────╯
func extractPeerInfo(c echo.Context) (string, string) {
var chal protocol.URLEncodedBase64
id, _ := common.ReadCookie(c, common.SessionID)
chalRaw, _ := common.ReadCookieBytes(c, common.SessionChallenge)
chal.UnmarshalJSON(chalRaw)
return id, common.Base64Encode(chal)
}
func extractBrowserInfo(c echo.Context) (string, string) {
secCHUA := common.HeaderRead(c, common.UserAgent)
// If common.is empty, return empty BrowserInfo
if secCHUA == "" {
return "N/A", "-1"
}
// Split the common.into individual browser entries
var (
name string
ver string
)
entries := strings.Split(strings.TrimSpace(secCHUA), ",")
for _, entry := range entries {
// Remove leading/trailing spaces and quotes
entry = strings.TrimSpace(entry)
// Use regex to extract the browser name and version
re := regexp.MustCompile(`"([^"]+)";v="([^"]+)"`)
matches := re.FindStringSubmatch(entry)
if len(matches) == 3 {
browserName := matches[1]
version := matches[2]
// Skip "Not A;Brand"
if !validBrowser(browserName) {
continue
}
// Store the first valid browser info as fallback
name = browserName
ver = version
}
}
return name, ver
}
func validBrowser(name string) bool {
return name != common.BrowserNameUnknown.String() && name != common.BrowserNameChromium.String()
}
// ╭───────────────────────────────────────────────────────────╮
// │ Authentication │
// ╰───────────────────────────────────────────────────────────╯
func buildUserEntity(userID string) protocol.UserEntity {
return protocol.UserEntity{
ID: userID,
}
}
// returns the base options for registering a new user without challenge or user entity.
func baseRegisterOptions() *protocol.PublicKeyCredentialCreationOptions {
return &protocol.PublicKeyCredentialCreationOptions{
Timeout: kWebAuthnTimeout,
Attestation: protocol.PreferDirectAttestation,
AuthenticatorSelection: protocol.AuthenticatorSelection{
AuthenticatorAttachment: "platform",
ResidentKey: protocol.ResidentKeyRequirementPreferred,
UserVerification: "preferred",
},
Parameters: []protocol.CredentialParameter{
{
Type: "public-key",
Algorithm: webauthncose.AlgES256,
},
{
Type: "public-key",
Algorithm: webauthncose.AlgES256K,
},
{
Type: "public-key",
Algorithm: webauthncose.AlgEdDSA,
},
},
}
}
func formatAuth(ucanCID string) string {
return "Bearer " + ucanCID
}
+90
View File
@@ -0,0 +1,90 @@
package session
import (
"encoding/json"
"net/http"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/common"
"github.com/onsonr/sonr/pkg/vault/types"
)
type SessionCtx interface {
ID() string
BrowserName() string
BrowserVersion() string
}
type contextKey string
// Context keys
const (
DataContextKey contextKey = "http_session_data"
)
// Get returns the session.Context from the echo context.
func Get(c echo.Context) (SessionCtx, error) {
ctx, ok := c.(*HTTPContext)
if !ok {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Session Context not found")
}
return ctx, nil
}
// WebNodeMiddleware establishes a Session Cookie.
func Middleware(config *types.Config) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
err := injectConfig(c, config)
if err != nil {
return err
}
cc := injectSession(c, common.RoleMotr)
return next(cc)
}
}
}
func injectConfig(c echo.Context, config *types.Config) error {
common.HeaderWrite(c, common.SonrAPIURL, config.SonrApiUrl)
common.HeaderWrite(c, common.SonrRPCURL, config.SonrRpcUrl)
common.WriteCookie(c, common.SonrAddress, config.MotrAddress)
schemaBz, err := json.Marshal(config.VaultSchema)
if err != nil {
return err
}
common.WriteCookieBytes(c, common.VaultSchema, schemaBz)
return nil
}
// injectSession returns the session injectSession from the cookies.
func injectSession(c echo.Context, role common.PeerRole) *HTTPContext {
if c == nil {
return initHTTPContext(nil)
}
common.WriteCookie(c, common.SessionRole, role.String())
// Continue even if there are errors, just ensure we have valid session data
if err := loadOrGenKsuid(c); err != nil {
// Log error but continue
}
return initHTTPContext(c)
}
// HasAuthorization checks if the request has an authorization header
func HasAuthorization(c echo.Context) bool {
return common.HeaderExists(c, common.Authorization)
}
// HasUserHandle checks if the request has a user handle cookie
func HasUserHandle(c echo.Context) bool {
return common.CookieExists(c, common.UserHandle)
}
// HasVaultAddress checks if the request has a vault address cookie
func HasVaultAddress(c echo.Context) bool {
return common.CookieExists(c, common.SonrAddress)
}
+51
View File
@@ -0,0 +1,51 @@
package session
import (
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/common"
)
// HTTPContext is the context for HTTP endpoints.
type HTTPContext struct {
echo.Context
role common.PeerRole
id string
chal string
bn string
bv string
}
// initHTTPContext loads the headers from the request.
func initHTTPContext(c echo.Context) *HTTPContext {
if c == nil {
return &HTTPContext{}
}
id, chal := extractPeerInfo(c)
bn, bv := extractBrowserInfo(c)
cc := &HTTPContext{
Context: c,
role: common.PeerRole(common.ReadCookieUnsafe(c, common.SessionRole)),
id: id,
chal: chal,
bn: bn,
bv: bv,
}
// Set the session data in both contexts
return cc
}
func (s *HTTPContext) ID() string {
return s.id
}
func (s *HTTPContext) BrowserName() string {
return s.bn
}
func (s *HTTPContext) BrowserVersion() string {
return s.bv
}
-1
View File
@@ -1 +0,0 @@
package middleware
-1
View File
@@ -1 +0,0 @@
package middleware
+7 -2
View File
@@ -1,16 +1,21 @@
//go:build js && wasm
// +build js,wasm
// Package vault provides the routes for the Decentralized Web Node (...or Sonr Motr).
package vault
import (
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/vault/handlers"
"github.com/onsonr/sonr/pkg/vault/internal/session"
"github.com/onsonr/sonr/pkg/vault/types"
)
// RegisterAPI registers the Decentralized Web Node API routes.
func RegisterAPI(e *echo.Echo) {
// RegisterRoutes registers the Decentralized Web Node API routes.
func RegisterRoutes(e *echo.Echo, config *types.Config) {
e.Use(session.Middleware(config))
e.GET("/register/:subject/start", handlers.RegisterSubjectStart)
e.POST("/register/:subject/finish", handlers.RegisterSubjectFinish)
-55
View File
@@ -1,55 +0,0 @@
package types
import (
"reflect"
"strings"
"github.com/onsonr/sonr/pkg/common/models"
)
const SchemaVersion = 1
// DefaultSchema returns the default schema
func DefaultSchema() *Schema {
return &Schema{
Version: SchemaVersion,
Account: getSchema(&models.Account{}),
Asset: getSchema(&models.Asset{}),
Chain: getSchema(&models.Chain{}),
Credential: getSchema(&models.Credential{}),
Grant: getSchema(&models.Grant{}),
Keyshare: getSchema(&models.Keyshare{}),
Profile: getSchema(&models.Profile{}),
}
}
func getSchema(structType interface{}) string {
t := reflect.TypeOf(structType)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return ""
}
var fields []string
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fieldName := toCamelCase(field.Name)
fields = append(fields, fieldName)
}
// Add "++" at the beginning, separated by a comma
return "++, " + strings.Join(fields, ", ")
}
func toCamelCase(s string) string {
if s == "" {
return s
}
if len(s) == 1 {
return strings.ToLower(s)
}
return strings.ToLower(s[:1]) + s[1:]
}
-137
View File
@@ -1,137 +0,0 @@
package types
func NewWebManifest() WebManifest {
return baseWebManifest
}
var baseWebManifest = WebManifest{
Name: "Sonr Vault",
ShortName: "Sonr.ID",
StartURL: "/index.html",
Display: "standalone",
DisplayOverride: []string{
"fullscreen",
"minimal-ui",
},
Icons: []IconDefinition{
{
Src: "/icons/icon-192x192.png",
Sizes: "192x192",
Type: "image/png",
},
},
ServiceWorker: ServiceWorker{
Scope: "/",
Src: "/sw.js",
UseCache: true,
},
ProtocolHandlers: []ProtocolHandler{
{
Scheme: "did.sonr",
URL: "/resolve/sonr/%s",
},
{
Scheme: "did.eth",
URL: "/resolve/eth/%s",
},
{
Scheme: "did.btc",
URL: "/resolve/btc/%s",
},
{
Scheme: "did.usdc",
URL: "/resolve/usdc/%s",
},
{
Scheme: "did.ipfs",
URL: "/resolve/ipfs/%s",
},
},
}
type WebManifest struct {
// Required fields
Name string `json:"name"` // Full name of the application
ShortName string `json:"short_name"` // Short version of the name
// Display and appearance
Description string `json:"description,omitempty"` // Purpose and features of the application
Display string `json:"display,omitempty"` // Preferred display mode: fullscreen, standalone, minimal-ui, browser
DisplayOverride []string `json:"display_override,omitempty"`
ThemeColor string `json:"theme_color,omitempty"` // Default theme color for the application
BackgroundColor string `json:"background_color,omitempty"` // Background color during launch
Orientation string `json:"orientation,omitempty"` // Default orientation: any, natural, landscape, portrait
// URLs and scope
StartURL string `json:"start_url"` // Starting URL when launching
Scope string `json:"scope,omitempty"` // Navigation scope of the web application
ServiceWorker ServiceWorker `json:"service_worker,omitempty"`
// Icons
Icons []IconDefinition `json:"icons,omitempty"`
// Optional features
RelatedApplications []RelatedApplication `json:"related_applications,omitempty"`
PreferRelatedApplications bool `json:"prefer_related_applications,omitempty"`
Shortcuts []Shortcut `json:"shortcuts,omitempty"`
// Experimental features (uncomment if needed)
FileHandlers []FileHandler `json:"file_handlers,omitempty"`
ProtocolHandlers []ProtocolHandler `json:"protocol_handlers,omitempty"`
}
type FileHandler struct {
Action string `json:"action"`
Accept map[string][]string `json:"accept"`
}
type LaunchHandler struct {
Action string `json:"action"`
}
type IconDefinition struct {
Src string `json:"src"`
Sizes string `json:"sizes"`
Type string `json:"type,omitempty"`
Purpose string `json:"purpose,omitempty"`
}
type ProtocolHandler struct {
Scheme string `json:"scheme"`
URL string `json:"url"`
}
type RelatedApplication struct {
Platform string `json:"platform"`
URL string `json:"url,omitempty"`
ID string `json:"id,omitempty"`
}
type Shortcut struct {
Name string `json:"name"`
ShortName string `json:"short_name,omitempty"`
Description string `json:"description,omitempty"`
URL string `json:"url"`
Icons []IconDefinition `json:"icons,omitempty"`
}
type ServiceWorker struct {
Scope string `json:"scope"`
Src string `json:"src"`
UseCache bool `json:"use_cache"`
}
// Example usage:
// manifest := WebManifest{
// Name: "My Amazing App",
// ShortName: "MyApp",
// StartURL: "/",
// Display: "standalone",
// Icons: []IconDefinition{
// {
// Src: "/icons/icon-192x192.png",
// Sizes: "192x192",
// Type: "image/png",
// },
// },
// }