mirror of
https://github.com/onsonr/sonr.git
synced 2025-03-10 13:07:09 +00:00
feat: implement passkey registration flow
This commit is contained in:
parent
b51c36645e
commit
04d929aae9
@ -16,27 +16,12 @@ var (
|
||||
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"`
|
||||
Address string `json:"address"`
|
||||
Handle string `json:"handle"`
|
||||
Name string `json:"name"`
|
||||
CID string `json:"cid"`
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
|
@ -20,7 +20,6 @@ func NewGormDB(env config.Env) (*gorm.DB, error) {
|
||||
// Migrate the schema
|
||||
db.AutoMigrate(&Session{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
|
@ -10,21 +10,21 @@ templ InitialView() {
|
||||
@layout.Container() {
|
||||
@text.Header("Sonr.ID", "The decentralized identity layer for the web.")
|
||||
<div class="pt-1.5 mb-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-button size="large" 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>
|
||||
<div class="pt-5 flex flex-row items-center justify-center h-full gap-2">
|
||||
<sl-button circle outline>
|
||||
<div class="pt-4 flex flex-row items-center justify-center h-full gap-3">
|
||||
<sl-button circle outline href="https://sonr.io">
|
||||
<sl-icon name="home" library="sonr" label="Home"></sl-icon>
|
||||
</sl-button>
|
||||
<sl-button circle outline>
|
||||
<sl-button circle outline href="https://onsonr.dev">
|
||||
<sl-icon name="docs" library="sonr" label="Docs"></sl-icon>
|
||||
</sl-button>
|
||||
<sl-button circle outline>
|
||||
<sl-icon name="question" label="About"></sl-icon>
|
||||
<sl-button circle outline href="https://github.com/onsonr/sonr">
|
||||
<sl-icon name="social-github" library="sonr" label="Open Source"></sl-icon>
|
||||
</sl-button>
|
||||
</div>
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func InitialView() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-1.5 mb-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><div class=\"pt-5 flex flex-row items-center justify-center h-full gap-2\"><sl-button circle outline><sl-icon name=\"home\" library=\"sonr\" label=\"Home\"></sl-icon></sl-button> <sl-button circle outline><sl-icon name=\"docs\" library=\"sonr\" label=\"Docs\"></sl-icon></sl-button> <sl-button circle outline><sl-icon name=\"question\" label=\"About\"></sl-icon></sl-button></div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-1.5 mb-3 flex flex-col items-center justify-center h-full\"><sl-button size=\"large\" 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><div class=\"pt-4 flex flex-row items-center justify-center h-full gap-3\"><sl-button circle outline href=\"https://sonr.io\"><sl-icon name=\"home\" library=\"sonr\" label=\"Home\"></sl-icon></sl-button> <sl-button circle outline href=\"https://onsonr.dev\"><sl-icon name=\"docs\" library=\"sonr\" label=\"Docs\"></sl-icon></sl-button> <sl-button circle outline href=\"https://github.com/onsonr/sonr\"><sl-icon name=\"social-github\" library=\"sonr\" label=\"Open Source\"></sl-icon></sl-button></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -6,9 +6,23 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/internal/database/sessions"
|
||||
)
|
||||
|
||||
// Define the credential structure matching our frontend data
|
||||
type Credential struct {
|
||||
Handle string `json:"handle"`
|
||||
ID string `json:"id"`
|
||||
RawID string `json:"rawId"`
|
||||
Type string `json:"type"`
|
||||
AuthenticatorAttachment string `json:"authenticatorAttachment"`
|
||||
Transports string `json:"transports"`
|
||||
ClientExtensionResults map[string]string `json:"clientExtensionResults"`
|
||||
Response struct {
|
||||
AttestationObject string `json:"attestationObject"`
|
||||
ClientDataJSON string `json:"clientDataJSON"`
|
||||
} `json:"response"`
|
||||
}
|
||||
|
||||
type CreateProfileData struct {
|
||||
TurnstileSiteKey string
|
||||
FirstNumber int
|
||||
@ -35,8 +49,8 @@ func (d CreateProfileData) IsHumanLabel() string {
|
||||
return fmt.Sprintf("What is %d + %d?", d.FirstNumber, d.LastNumber)
|
||||
}
|
||||
|
||||
func extractCredentialDescriptor(jsonString string) (*sessions.Credential, error) {
|
||||
cred := &sessions.Credential{}
|
||||
func extractCredentialDescriptor(jsonString string) (*Credential, error) {
|
||||
cred := &Credential{}
|
||||
// Unmarshal the credential JSON
|
||||
if err := json.Unmarshal([]byte(jsonString), cred); err != nil {
|
||||
return nil, echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("invalid credential format: %v", err))
|
||||
|
@ -4,7 +4,7 @@ import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
templ formCreateProfile(action string, method string, data CreateProfileData) {
|
||||
<form action={ templ.SafeURL(action) } method={ method }>
|
||||
<sl-card class="card-form gap-6 w-full max-w-2xl mx-auto px-4 sm:px-8">
|
||||
<sl-card class="card-form gap-6 w-full max-w-xl">
|
||||
<div slot="header">
|
||||
<div class="w-full py-1">
|
||||
<sl-progress-bar value="50"></sl-progress-bar>
|
||||
@ -63,7 +63,7 @@ templ formCreateProfile(action string, method string, data CreateProfileData) {
|
||||
templ formRegisterPasskey(action, method string, data RegisterPasskeyData) {
|
||||
<form action={ templ.SafeURL(action) } method={ method } id="passkey-form">
|
||||
<input type="hidden" name="credential" id="credential-data" required/>
|
||||
<sl-card class="card-form gap-4 max-w-lg">
|
||||
<sl-card class="card-form gap-4 max-w-xl">
|
||||
<div slot="header">
|
||||
<div class="w-full py-2">
|
||||
@sonrProfile(data.Address, data.Name, data.Handle, data.CreationBlock)
|
||||
@ -123,4 +123,3 @@ templ formRegisterPasskey(action, method string, data RegisterPasskeyData) {
|
||||
</sl-card>
|
||||
</form>
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ func formCreateProfile(action string, method string, data CreateProfileData) tem
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><sl-card class=\"card-form gap-6 w-full max-w-2xl mx-auto px-4 sm:px-8\"><div slot=\"header\"><div class=\"w-full py-1\"><sl-progress-bar value=\"50\"></sl-progress-bar></div></div><div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\"><sl-input name=\"first_name\" placeholder=\"Satoshi\" type=\"text\" label=\"First Name\" required autofocus></sl-input> <sl-input name=\"last_name\" placeholder=\"N\" maxlength=\"1\" type=\"text\" label=\"Last Initial\"></sl-input></div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><sl-card class=\"card-form gap-6 w-full max-w-xl\"><div slot=\"header\"><div class=\"w-full py-1\"><sl-progress-bar value=\"50\"></sl-progress-bar></div></div><div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\"><sl-input name=\"first_name\" placeholder=\"Satoshi\" type=\"text\" label=\"First Name\" required autofocus></sl-input> <sl-input name=\"last_name\" placeholder=\"N\" maxlength=\"1\" type=\"text\" label=\"Last Initial\"></sl-input></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -133,7 +133,7 @@ func formRegisterPasskey(action, method string, data RegisterPasskeyData) templ.
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" id=\"passkey-form\"><input type=\"hidden\" name=\"credential\" id=\"credential-data\" required> <sl-card class=\"card-form gap-4 max-w-lg\"><div slot=\"header\"><div class=\"w-full py-2\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" id=\"passkey-form\"><input type=\"hidden\" name=\"credential\" id=\"credential-data\" required> <sl-card class=\"card-form gap-4 max-w-xl\"><div slot=\"header\"><div class=\"w-full py-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user