mirror of
https://github.com/onsonr/sonr.git
synced 2025-03-10 04:57:08 +00:00
feature/1111 sync chain dwn endpoint (#1143)
- **feat(did): add assertion type to DID spec** - **refactor: update build process to include assets generation** - **refactor: update import paths for to** - **feat: introduce new authentication state management** - **feat: add current account route** - **feat: implement global toasts with custom HTML** - **refactor: remove unused session code** - **feat: add config.json to embedded assets** - **refactor: remove unused dependency on gorilla/sessions** - **refactor: simplify session management and remove unnecessary fields** - **fix: remove unnecessary import for unused protobuf types** - **feat: introduce separate HTTP contexts for Highway and DWN** - **fix(keeper): Handle missing controller during initial sync** - **refactor: extract DWN configuration from DWNContext** - **feat: add view route** - **fix: update configuration file name in embed.go** - **feat: improve vaultindex page loading experience** - **feat(hway): add highway context to echo context** - **chore(deps): bump onsonr/crypto from 1.32.0 to 1.33.0** - **refactor: rename DWNSessionMiddleware to WebNodeSessionMiddleware** - **feat: rename client API to web node API** - **refactor: separate API and view routes** - **refactor: remove unused build targets in Makefile** - **feat: add Devbox integration to container** - **feat: add wasm support for dwn** - **refactor: update module proto import** - **feat: add default first and third party caveats** - **feat: Add target vault allocation mechanism** - **refactor: introduce standardized session cookie handling** - **fix: update service worker installation and ready states** - **feat: add worker handlers** - **feat: Enable SSH access to devcontainer** - **refactor: rename HighwayContext to HwayContext** - **feat: add block expiration calculation to sonr context** - **feat: remove config from cookie and header** - **feat(gen): Remove generated code for IPFS, Motr and Sonr** - **refactor: remove unused createMotrConfig function** - **feat: add project analytics with Repobeats** - **docs: Remove component details from README** - **refactor: rename SetConfig to injectConfig**
This commit is contained in:
parent
104df074e9
commit
b6c49828ed
15
.devcontainer/Dockerfile
Normal file
15
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM jetpackio/devbox:latest
|
||||
|
||||
# Installing your devbox project
|
||||
WORKDIR /code
|
||||
USER root:root
|
||||
RUN mkdir -p /code && chown ${DEVBOX_USER}:${DEVBOX_USER} /code
|
||||
USER ${DEVBOX_USER}:${DEVBOX_USER}
|
||||
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.json devbox.json
|
||||
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.lock devbox.lock
|
||||
|
||||
|
||||
|
||||
RUN devbox run -- echo "Installed Packages."
|
||||
|
||||
RUN devbox shellenv --init-hook >> ~/.profile
|
21
.devcontainer/devcontainer.json
Normal file
21
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Devbox Remote Container",
|
||||
"build": {
|
||||
"dockerfile": "./Dockerfile",
|
||||
"context": ".."
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/sshd:1": {
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
"extensions": [
|
||||
"jetpack-io.devbox"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remoteUser": "devbox"
|
||||
}
|
32
Makefile
32
Makefile
@ -296,6 +296,10 @@ sh-testnet: mod-tidy
|
||||
|
||||
.PHONY: templ-gen pkl-gen
|
||||
|
||||
assets-gen:
|
||||
@echo "(assets) Generating gateway cloudflare workers assets"
|
||||
go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go -o ./cmd/hway/build
|
||||
|
||||
templ-gen:
|
||||
@echo "(templ) Generating templ files"
|
||||
templ generate
|
||||
@ -306,34 +310,6 @@ pkl-gen:
|
||||
go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/ORM.pkl
|
||||
go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/Txns.pkl
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
### motr, hway & nebula ###
|
||||
###############################################################################
|
||||
|
||||
.PHONY: motr-build hway-build nebula-build
|
||||
|
||||
nebula-build:
|
||||
@echo "(ui) Building nebula"
|
||||
cd pkg/nebula && bun install && bun run build
|
||||
|
||||
motr-build: nebula-build templ-gen pkl-gen
|
||||
@echo "(dwn) Building motr.wasm -> Service Worker IPFS Vault"
|
||||
GOOS=js GOARCH=wasm go build -o ./pkg/dwn/app.wasm ./cmd/motr/main.go
|
||||
|
||||
hway-build: nebula-build templ-gen
|
||||
@echo "(hway) Building Highway gateway"
|
||||
GOOS=js GOARCH=wasm go build -o ./cmd/hway/build/app.wasm ./cmd/hway/main.go
|
||||
|
||||
hway-dev:
|
||||
@echo "(hway) Serving Highway gateway"
|
||||
bunx wrangler dev
|
||||
|
||||
hway-deploy:
|
||||
@echo "(hway) Deploying Highway gateway"
|
||||
bunx wrangler deploy
|
||||
|
||||
###############################################################################
|
||||
### help ###
|
||||
###############################################################################
|
||||
|
28
README.md
28
README.md
@ -1,37 +1,23 @@
|
||||
<div align="center" style="text-align: center;">
|
||||
|
||||
# `sonr` - Sonr Chain
|
||||
|
||||
<center>
|
||||
|
||||
[](https://pkg.go.dev/github.com/onsonr/sonr)
|
||||

|
||||

|
||||
[](https://sonr.io)
|
||||
|
||||
[](https://goreportcard.com/report/github.com/onsonr/sonr)
|
||||
[](https://sonarcloud.io/summary/new_code?id=sonr-io_sonr)
|
||||
|
||||
</div>
|
||||
<br />
|
||||
</center>
|
||||
|
||||
## Overview
|
||||
|
||||
Sonr is a combination of decentralized primitives. Fundamentally, it is a peer-to-peer identity and asset management system that leverages DID documents, Webauthn, and IPFS—providing users with a secure, portable decentralized identity.
|
||||
|
||||
<br />
|
||||
## Stats
|
||||
|
||||
## Components
|
||||
|
||||
### `sonrd`
|
||||
|
||||
The main blockchain node that runs the `sonr` chain. It is responsible for maintaining the state of the chain, including IPFS based vaults, and did documents.
|
||||
|
||||
### `vault`
|
||||
|
||||
The `vault` is a wasm module that is compiled and deployed to IPFS on behalf of the user. It is responsible for storing and retrieving encrypted data.
|
||||
|
||||
- SQLite Database backend
|
||||
- Encryption via admonition
|
||||
- Authentication via webauthn
|
||||
- Authorization via Macroons
|
||||
- HTTP API
|
||||

|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
39
Taskfile.yml
Normal file
39
Taskfile.yml
Normal file
@ -0,0 +1,39 @@
|
||||
version: "3"
|
||||
|
||||
vars:
|
||||
ROOT_DIR:
|
||||
sh: pwd
|
||||
|
||||
tasks:
|
||||
hway:build:
|
||||
dir: cmd/hway
|
||||
env:
|
||||
GOOS: js
|
||||
GOARCH: wasm
|
||||
cmds:
|
||||
- go build -o build/app.wasm main.go
|
||||
|
||||
hway:dev:
|
||||
dir: cmd/hway
|
||||
cmds:
|
||||
- bunx wrangler dev
|
||||
|
||||
hway:deploy:
|
||||
dir: cmd/hway
|
||||
cmds:
|
||||
- bunx wrangler deploy
|
||||
|
||||
motr:build:
|
||||
dir: internal/dwn
|
||||
env:
|
||||
GOOS: js
|
||||
GOARCH: wasm
|
||||
cmds:
|
||||
- go build -o app.wasm wasm/main.go
|
||||
|
||||
nebula:build:
|
||||
dir: pkg/nebula
|
||||
cmds:
|
||||
- bun install
|
||||
- bun run deps.mjs
|
||||
- bunx tailwindcss -i ./global/styles/globals.css -o ./assets/css/styles.css
|
@ -104,9 +104,9 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
switch fd.FullName() {
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module"))
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
|
||||
}
|
||||
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +120,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) {
|
||||
switch fd.FullName() {
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module"))
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
|
||||
}
|
||||
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,9 +136,9 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro
|
||||
switch descriptor.FullName() {
|
||||
default:
|
||||
if descriptor.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module"))
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
|
||||
}
|
||||
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", descriptor.FullName()))
|
||||
panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", descriptor.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,9 +156,9 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto
|
||||
switch fd.FullName() {
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module"))
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
|
||||
}
|
||||
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,9 +176,9 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore
|
||||
switch fd.FullName() {
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module"))
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
|
||||
}
|
||||
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,9 +189,9 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor
|
||||
switch fd.FullName() {
|
||||
default:
|
||||
if fd.IsExtension() {
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module"))
|
||||
panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module"))
|
||||
}
|
||||
panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor
|
||||
func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
switch d.FullName() {
|
||||
default:
|
||||
panic(fmt.Errorf("%s is not a oneof field in onsonr.sonr.did.module.v1.Module", d.FullName()))
|
||||
panic(fmt.Errorf("%s is not a oneof field in did.module.v1.Module", d.FullName()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
@ -414,29 +414,24 @@ var File_did_module_v1_module_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_did_module_v1_module_proto_rawDesc = []byte{
|
||||
0x0a, 0x1a, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x6e,
|
||||
0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f,
|
||||
0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f,
|
||||
0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64,
|
||||
0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x6f, 0x64,
|
||||
0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, 0x16, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73,
|
||||
0x6f, 0x6e, 0x72, 0x42, 0xe8, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x6f, 0x6e, 0x73, 0x6f,
|
||||
0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75,
|
||||
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d,
|
||||
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x04, 0x4f, 0x53, 0x44, 0x4d, 0xaa, 0x02,
|
||||
0x19, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x53, 0x6f, 0x6e, 0x72, 0x2e, 0x44, 0x69, 0x64,
|
||||
0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x19, 0x4f, 0x6e, 0x73,
|
||||
0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64,
|
||||
0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x25, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x5c,
|
||||
0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c,
|
||||
0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
|
||||
0x1d, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x53, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x44,
|
||||
0x69, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x69,
|
||||
0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73,
|
||||
0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
|
||||
0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a,
|
||||
0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a,
|
||||
0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f,
|
||||
0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xa9, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d,
|
||||
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f,
|
||||
0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64,
|
||||
0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2,
|
||||
0x02, 0x03, 0x44, 0x4d, 0x58, 0xaa, 0x02, 0x0d, 0x44, 0x69, 0x64, 0x2e, 0x4d, 0x6f, 0x64, 0x75,
|
||||
0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75,
|
||||
0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75,
|
||||
0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0xea, 0x02, 0x0f, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a,
|
||||
0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -453,7 +448,7 @@ func file_did_module_v1_module_proto_rawDescGZIP() []byte {
|
||||
|
||||
var file_did_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_did_module_v1_module_proto_goTypes = []interface{}{
|
||||
(*Module)(nil), // 0: onsonr.sonr.did.module.v1.Module
|
||||
(*Module)(nil), // 0: did.module.v1.Module
|
||||
}
|
||||
var file_did_module_v1_module_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
|
@ -9,6 +9,163 @@ import (
|
||||
ormerrors "cosmossdk.io/orm/types/ormerrors"
|
||||
)
|
||||
|
||||
type AssertionTable interface {
|
||||
Insert(ctx context.Context, assertion *Assertion) error
|
||||
Update(ctx context.Context, assertion *Assertion) error
|
||||
Save(ctx context.Context, assertion *Assertion) error
|
||||
Delete(ctx context.Context, assertion *Assertion) error
|
||||
Has(ctx context.Context, did string) (found bool, err error)
|
||||
// Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found.
|
||||
Get(ctx context.Context, did string) (*Assertion, error)
|
||||
HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error)
|
||||
// GetByControllerSubject returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found.
|
||||
GetByControllerSubject(ctx context.Context, controller string, subject string) (*Assertion, error)
|
||||
List(ctx context.Context, prefixKey AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error)
|
||||
ListRange(ctx context.Context, from, to AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error)
|
||||
DeleteBy(ctx context.Context, prefixKey AssertionIndexKey) error
|
||||
DeleteRange(ctx context.Context, from, to AssertionIndexKey) error
|
||||
|
||||
doNotImplement()
|
||||
}
|
||||
|
||||
type AssertionIterator struct {
|
||||
ormtable.Iterator
|
||||
}
|
||||
|
||||
func (i AssertionIterator) Value() (*Assertion, error) {
|
||||
var assertion Assertion
|
||||
err := i.UnmarshalMessage(&assertion)
|
||||
return &assertion, err
|
||||
}
|
||||
|
||||
type AssertionIndexKey interface {
|
||||
id() uint32
|
||||
values() []interface{}
|
||||
assertionIndexKey()
|
||||
}
|
||||
|
||||
// primary key starting index..
|
||||
type AssertionPrimaryKey = AssertionDidIndexKey
|
||||
|
||||
type AssertionDidIndexKey struct {
|
||||
vs []interface{}
|
||||
}
|
||||
|
||||
func (x AssertionDidIndexKey) id() uint32 { return 0 }
|
||||
func (x AssertionDidIndexKey) values() []interface{} { return x.vs }
|
||||
func (x AssertionDidIndexKey) assertionIndexKey() {}
|
||||
|
||||
func (this AssertionDidIndexKey) WithDid(did string) AssertionDidIndexKey {
|
||||
this.vs = []interface{}{did}
|
||||
return this
|
||||
}
|
||||
|
||||
type AssertionControllerSubjectIndexKey struct {
|
||||
vs []interface{}
|
||||
}
|
||||
|
||||
func (x AssertionControllerSubjectIndexKey) id() uint32 { return 1 }
|
||||
func (x AssertionControllerSubjectIndexKey) values() []interface{} { return x.vs }
|
||||
func (x AssertionControllerSubjectIndexKey) assertionIndexKey() {}
|
||||
|
||||
func (this AssertionControllerSubjectIndexKey) WithController(controller string) AssertionControllerSubjectIndexKey {
|
||||
this.vs = []interface{}{controller}
|
||||
return this
|
||||
}
|
||||
|
||||
func (this AssertionControllerSubjectIndexKey) WithControllerSubject(controller string, subject string) AssertionControllerSubjectIndexKey {
|
||||
this.vs = []interface{}{controller, subject}
|
||||
return this
|
||||
}
|
||||
|
||||
type assertionTable struct {
|
||||
table ormtable.Table
|
||||
}
|
||||
|
||||
func (this assertionTable) Insert(ctx context.Context, assertion *Assertion) error {
|
||||
return this.table.Insert(ctx, assertion)
|
||||
}
|
||||
|
||||
func (this assertionTable) Update(ctx context.Context, assertion *Assertion) error {
|
||||
return this.table.Update(ctx, assertion)
|
||||
}
|
||||
|
||||
func (this assertionTable) Save(ctx context.Context, assertion *Assertion) error {
|
||||
return this.table.Save(ctx, assertion)
|
||||
}
|
||||
|
||||
func (this assertionTable) Delete(ctx context.Context, assertion *Assertion) error {
|
||||
return this.table.Delete(ctx, assertion)
|
||||
}
|
||||
|
||||
func (this assertionTable) Has(ctx context.Context, did string) (found bool, err error) {
|
||||
return this.table.PrimaryKey().Has(ctx, did)
|
||||
}
|
||||
|
||||
func (this assertionTable) Get(ctx context.Context, did string) (*Assertion, error) {
|
||||
var assertion Assertion
|
||||
found, err := this.table.PrimaryKey().Get(ctx, &assertion, did)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !found {
|
||||
return nil, ormerrors.NotFound
|
||||
}
|
||||
return &assertion, nil
|
||||
}
|
||||
|
||||
func (this assertionTable) HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) {
|
||||
return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx,
|
||||
controller,
|
||||
subject,
|
||||
)
|
||||
}
|
||||
|
||||
func (this assertionTable) GetByControllerSubject(ctx context.Context, controller string, subject string) (*Assertion, error) {
|
||||
var assertion Assertion
|
||||
found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &assertion,
|
||||
controller,
|
||||
subject,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !found {
|
||||
return nil, ormerrors.NotFound
|
||||
}
|
||||
return &assertion, nil
|
||||
}
|
||||
|
||||
func (this assertionTable) List(ctx context.Context, prefixKey AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) {
|
||||
it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...)
|
||||
return AssertionIterator{it}, err
|
||||
}
|
||||
|
||||
func (this assertionTable) ListRange(ctx context.Context, from, to AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) {
|
||||
it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...)
|
||||
return AssertionIterator{it}, err
|
||||
}
|
||||
|
||||
func (this assertionTable) DeleteBy(ctx context.Context, prefixKey AssertionIndexKey) error {
|
||||
return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...)
|
||||
}
|
||||
|
||||
func (this assertionTable) DeleteRange(ctx context.Context, from, to AssertionIndexKey) error {
|
||||
return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values())
|
||||
}
|
||||
|
||||
func (this assertionTable) doNotImplement() {}
|
||||
|
||||
var _ AssertionTable = assertionTable{}
|
||||
|
||||
func NewAssertionTable(db ormtable.Schema) (AssertionTable, error) {
|
||||
table := db.GetTable(&Assertion{})
|
||||
if table == nil {
|
||||
return nil, ormerrors.TableNotFound.Wrap(string((&Assertion{}).ProtoReflect().Descriptor().FullName()))
|
||||
}
|
||||
return assertionTable{table}, nil
|
||||
}
|
||||
|
||||
type AuthenticationTable interface {
|
||||
Insert(ctx context.Context, authentication *Authentication) error
|
||||
Update(ctx context.Context, authentication *Authentication) error
|
||||
@ -692,6 +849,7 @@ func NewVerificationTable(db ormtable.Schema) (VerificationTable, error) {
|
||||
}
|
||||
|
||||
type StateStore interface {
|
||||
AssertionTable() AssertionTable
|
||||
AuthenticationTable() AuthenticationTable
|
||||
ControllerTable() ControllerTable
|
||||
VerificationTable() VerificationTable
|
||||
@ -700,11 +858,16 @@ type StateStore interface {
|
||||
}
|
||||
|
||||
type stateStore struct {
|
||||
assertion AssertionTable
|
||||
authentication AuthenticationTable
|
||||
controller ControllerTable
|
||||
verification VerificationTable
|
||||
}
|
||||
|
||||
func (x stateStore) AssertionTable() AssertionTable {
|
||||
return x.assertion
|
||||
}
|
||||
|
||||
func (x stateStore) AuthenticationTable() AuthenticationTable {
|
||||
return x.authentication
|
||||
}
|
||||
@ -722,6 +885,11 @@ func (stateStore) doNotImplement() {}
|
||||
var _ StateStore = stateStore{}
|
||||
|
||||
func NewStateStore(db ormtable.Schema) (StateStore, error) {
|
||||
assertionTable, err := NewAssertionTable(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authenticationTable, err := NewAuthenticationTable(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -738,6 +906,7 @@ func NewStateStore(db ormtable.Schema) (StateStore, error) {
|
||||
}
|
||||
|
||||
return stateStore{
|
||||
assertionTable,
|
||||
authenticationTable,
|
||||
controllerTable,
|
||||
verificationTable,
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,10 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
Msg_ExecuteTx_FullMethodName = "/did.v1.Msg/ExecuteTx"
|
||||
Msg_RegisterController_FullMethodName = "/did.v1.Msg/RegisterController"
|
||||
Msg_LinkAssertion_FullMethodName = "/did.v1.Msg/LinkAssertion"
|
||||
Msg_LinkAuthentication_FullMethodName = "/did.v1.Msg/LinkAuthentication"
|
||||
Msg_UnlinkAssertion_FullMethodName = "/did.v1.Msg/UnlinkAssertion"
|
||||
Msg_UnlinkAuthentication_FullMethodName = "/did.v1.Msg/UnlinkAuthentication"
|
||||
Msg_UpdateParams_FullMethodName = "/did.v1.Msg/UpdateParams"
|
||||
)
|
||||
|
||||
@ -31,9 +34,14 @@ type MsgClient interface {
|
||||
// ExecuteTx executes a transaction on the Sonr Blockchain. It leverages
|
||||
// Macaroon for verification.
|
||||
ExecuteTx(ctx context.Context, in *MsgExecuteTx, opts ...grpc.CallOption) (*MsgExecuteTxResponse, error)
|
||||
// RegisterController initializes a controller with the given authentication
|
||||
// set, address, cid, publicKey, and user-defined alias.
|
||||
RegisterController(ctx context.Context, in *MsgRegisterController, opts ...grpc.CallOption) (*MsgRegisterControllerResponse, error)
|
||||
// LinkAssertion links an assertion to a controller.
|
||||
LinkAssertion(ctx context.Context, in *MsgLinkAssertion, opts ...grpc.CallOption) (*MsgLinkAssertionResponse, error)
|
||||
// LinkAuthentication links an authentication to a controller.
|
||||
LinkAuthentication(ctx context.Context, in *MsgLinkAuthentication, opts ...grpc.CallOption) (*MsgLinkAuthenticationResponse, error)
|
||||
// UnlinkAssertion unlinks an assertion from a controller.
|
||||
UnlinkAssertion(ctx context.Context, in *MsgUnlinkAssertion, opts ...grpc.CallOption) (*MsgUnlinkAssertionResponse, error)
|
||||
// UnlinkAuthentication unlinks an authentication from a controller.
|
||||
UnlinkAuthentication(ctx context.Context, in *MsgUnlinkAuthentication, opts ...grpc.CallOption) (*MsgUnlinkAuthenticationResponse, error)
|
||||
// UpdateParams defines a governance operation for updating the parameters.
|
||||
UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error)
|
||||
}
|
||||
@ -55,9 +63,36 @@ func (c *msgClient) ExecuteTx(ctx context.Context, in *MsgExecuteTx, opts ...grp
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *msgClient) RegisterController(ctx context.Context, in *MsgRegisterController, opts ...grpc.CallOption) (*MsgRegisterControllerResponse, error) {
|
||||
out := new(MsgRegisterControllerResponse)
|
||||
err := c.cc.Invoke(ctx, Msg_RegisterController_FullMethodName, in, out, opts...)
|
||||
func (c *msgClient) LinkAssertion(ctx context.Context, in *MsgLinkAssertion, opts ...grpc.CallOption) (*MsgLinkAssertionResponse, error) {
|
||||
out := new(MsgLinkAssertionResponse)
|
||||
err := c.cc.Invoke(ctx, Msg_LinkAssertion_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *msgClient) LinkAuthentication(ctx context.Context, in *MsgLinkAuthentication, opts ...grpc.CallOption) (*MsgLinkAuthenticationResponse, error) {
|
||||
out := new(MsgLinkAuthenticationResponse)
|
||||
err := c.cc.Invoke(ctx, Msg_LinkAuthentication_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *msgClient) UnlinkAssertion(ctx context.Context, in *MsgUnlinkAssertion, opts ...grpc.CallOption) (*MsgUnlinkAssertionResponse, error) {
|
||||
out := new(MsgUnlinkAssertionResponse)
|
||||
err := c.cc.Invoke(ctx, Msg_UnlinkAssertion_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *msgClient) UnlinkAuthentication(ctx context.Context, in *MsgUnlinkAuthentication, opts ...grpc.CallOption) (*MsgUnlinkAuthenticationResponse, error) {
|
||||
out := new(MsgUnlinkAuthenticationResponse)
|
||||
err := c.cc.Invoke(ctx, Msg_UnlinkAuthentication_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -80,9 +115,14 @@ type MsgServer interface {
|
||||
// ExecuteTx executes a transaction on the Sonr Blockchain. It leverages
|
||||
// Macaroon for verification.
|
||||
ExecuteTx(context.Context, *MsgExecuteTx) (*MsgExecuteTxResponse, error)
|
||||
// RegisterController initializes a controller with the given authentication
|
||||
// set, address, cid, publicKey, and user-defined alias.
|
||||
RegisterController(context.Context, *MsgRegisterController) (*MsgRegisterControllerResponse, error)
|
||||
// LinkAssertion links an assertion to a controller.
|
||||
LinkAssertion(context.Context, *MsgLinkAssertion) (*MsgLinkAssertionResponse, error)
|
||||
// LinkAuthentication links an authentication to a controller.
|
||||
LinkAuthentication(context.Context, *MsgLinkAuthentication) (*MsgLinkAuthenticationResponse, error)
|
||||
// UnlinkAssertion unlinks an assertion from a controller.
|
||||
UnlinkAssertion(context.Context, *MsgUnlinkAssertion) (*MsgUnlinkAssertionResponse, error)
|
||||
// UnlinkAuthentication unlinks an authentication from a controller.
|
||||
UnlinkAuthentication(context.Context, *MsgUnlinkAuthentication) (*MsgUnlinkAuthenticationResponse, error)
|
||||
// UpdateParams defines a governance operation for updating the parameters.
|
||||
UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error)
|
||||
mustEmbedUnimplementedMsgServer()
|
||||
@ -95,8 +135,17 @@ type UnimplementedMsgServer struct {
|
||||
func (UnimplementedMsgServer) ExecuteTx(context.Context, *MsgExecuteTx) (*MsgExecuteTxResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ExecuteTx not implemented")
|
||||
}
|
||||
func (UnimplementedMsgServer) RegisterController(context.Context, *MsgRegisterController) (*MsgRegisterControllerResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RegisterController not implemented")
|
||||
func (UnimplementedMsgServer) LinkAssertion(context.Context, *MsgLinkAssertion) (*MsgLinkAssertionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method LinkAssertion not implemented")
|
||||
}
|
||||
func (UnimplementedMsgServer) LinkAuthentication(context.Context, *MsgLinkAuthentication) (*MsgLinkAuthenticationResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method LinkAuthentication not implemented")
|
||||
}
|
||||
func (UnimplementedMsgServer) UnlinkAssertion(context.Context, *MsgUnlinkAssertion) (*MsgUnlinkAssertionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UnlinkAssertion not implemented")
|
||||
}
|
||||
func (UnimplementedMsgServer) UnlinkAuthentication(context.Context, *MsgUnlinkAuthentication) (*MsgUnlinkAuthenticationResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UnlinkAuthentication not implemented")
|
||||
}
|
||||
func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented")
|
||||
@ -132,20 +181,74 @@ func _Msg_ExecuteTx_Handler(srv interface{}, ctx context.Context, dec func(inter
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_RegisterController_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MsgRegisterController)
|
||||
func _Msg_LinkAssertion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MsgLinkAssertion)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MsgServer).RegisterController(ctx, in)
|
||||
return srv.(MsgServer).LinkAssertion(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Msg_RegisterController_FullMethodName,
|
||||
FullMethod: Msg_LinkAssertion_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MsgServer).RegisterController(ctx, req.(*MsgRegisterController))
|
||||
return srv.(MsgServer).LinkAssertion(ctx, req.(*MsgLinkAssertion))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_LinkAuthentication_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MsgLinkAuthentication)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MsgServer).LinkAuthentication(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Msg_LinkAuthentication_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MsgServer).LinkAuthentication(ctx, req.(*MsgLinkAuthentication))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_UnlinkAssertion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MsgUnlinkAssertion)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MsgServer).UnlinkAssertion(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Msg_UnlinkAssertion_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MsgServer).UnlinkAssertion(ctx, req.(*MsgUnlinkAssertion))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_UnlinkAuthentication_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MsgUnlinkAuthentication)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MsgServer).UnlinkAuthentication(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Msg_UnlinkAuthentication_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MsgServer).UnlinkAuthentication(ctx, req.(*MsgUnlinkAuthentication))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@ -180,8 +283,20 @@ var Msg_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _Msg_ExecuteTx_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RegisterController",
|
||||
Handler: _Msg_RegisterController_Handler,
|
||||
MethodName: "LinkAssertion",
|
||||
Handler: _Msg_LinkAssertion_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "LinkAuthentication",
|
||||
Handler: _Msg_LinkAuthentication_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UnlinkAssertion",
|
||||
Handler: _Msg_UnlinkAssertion_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UnlinkAuthentication",
|
||||
Handler: _Msg_UnlinkAuthentication_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateParams",
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,9 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
const (
|
||||
Query_Params_FullMethodName = "/vault.v1.Query/Params"
|
||||
Query_Schema_FullMethodName = "/vault.v1.Query/Schema"
|
||||
Query_Sync_FullMethodName = "/vault.v1.Query/Sync"
|
||||
Query_Allocate_FullMethodName = "/vault.v1.Query/Allocate"
|
||||
Query_SyncInitial_FullMethodName = "/vault.v1.Query/SyncInitial"
|
||||
Query_SyncCurrent_FullMethodName = "/vault.v1.Query/SyncCurrent"
|
||||
)
|
||||
|
||||
// QueryClient is the client API for Query service.
|
||||
@ -33,9 +35,15 @@ type QueryClient interface {
|
||||
// Schema queries the DID document by its id. And returns the required PKL
|
||||
// information
|
||||
Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error)
|
||||
// Allocate initializes a Target Vault available for claims with a compatible
|
||||
// Authentication mechanism. The default authentication mechanism is WebAuthn.
|
||||
Allocate(ctx context.Context, in *AllocateRequest, opts ...grpc.CallOption) (*AllocateResponse, error)
|
||||
// Sync queries the DID document by its id. And returns the required PKL
|
||||
// information
|
||||
Sync(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error)
|
||||
SyncInitial(ctx context.Context, in *SyncInitialRequest, opts ...grpc.CallOption) (*SyncInitialResponse, error)
|
||||
// SyncCurrent queries the DID document by its id. And returns the required PKL
|
||||
// information
|
||||
SyncCurrent(ctx context.Context, in *SyncCurrentRequest, opts ...grpc.CallOption) (*SyncCurrentResponse, error)
|
||||
}
|
||||
|
||||
type queryClient struct {
|
||||
@ -64,9 +72,27 @@ func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts .
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *queryClient) Sync(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) {
|
||||
out := new(SyncResponse)
|
||||
err := c.cc.Invoke(ctx, Query_Sync_FullMethodName, in, out, opts...)
|
||||
func (c *queryClient) Allocate(ctx context.Context, in *AllocateRequest, opts ...grpc.CallOption) (*AllocateResponse, error) {
|
||||
out := new(AllocateResponse)
|
||||
err := c.cc.Invoke(ctx, Query_Allocate_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *queryClient) SyncInitial(ctx context.Context, in *SyncInitialRequest, opts ...grpc.CallOption) (*SyncInitialResponse, error) {
|
||||
out := new(SyncInitialResponse)
|
||||
err := c.cc.Invoke(ctx, Query_SyncInitial_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *queryClient) SyncCurrent(ctx context.Context, in *SyncCurrentRequest, opts ...grpc.CallOption) (*SyncCurrentResponse, error) {
|
||||
out := new(SyncCurrentResponse)
|
||||
err := c.cc.Invoke(ctx, Query_SyncCurrent_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -82,9 +108,15 @@ type QueryServer interface {
|
||||
// Schema queries the DID document by its id. And returns the required PKL
|
||||
// information
|
||||
Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error)
|
||||
// Allocate initializes a Target Vault available for claims with a compatible
|
||||
// Authentication mechanism. The default authentication mechanism is WebAuthn.
|
||||
Allocate(context.Context, *AllocateRequest) (*AllocateResponse, error)
|
||||
// Sync queries the DID document by its id. And returns the required PKL
|
||||
// information
|
||||
Sync(context.Context, *SyncRequest) (*SyncResponse, error)
|
||||
SyncInitial(context.Context, *SyncInitialRequest) (*SyncInitialResponse, error)
|
||||
// SyncCurrent queries the DID document by its id. And returns the required PKL
|
||||
// information
|
||||
SyncCurrent(context.Context, *SyncCurrentRequest) (*SyncCurrentResponse, error)
|
||||
mustEmbedUnimplementedQueryServer()
|
||||
}
|
||||
|
||||
@ -98,8 +130,14 @@ func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*Q
|
||||
func (UnimplementedQueryServer) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented")
|
||||
}
|
||||
func (UnimplementedQueryServer) Sync(context.Context, *SyncRequest) (*SyncResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Sync not implemented")
|
||||
func (UnimplementedQueryServer) Allocate(context.Context, *AllocateRequest) (*AllocateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Allocate not implemented")
|
||||
}
|
||||
func (UnimplementedQueryServer) SyncInitial(context.Context, *SyncInitialRequest) (*SyncInitialResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SyncInitial not implemented")
|
||||
}
|
||||
func (UnimplementedQueryServer) SyncCurrent(context.Context, *SyncCurrentRequest) (*SyncCurrentResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SyncCurrent not implemented")
|
||||
}
|
||||
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
|
||||
|
||||
@ -150,20 +188,56 @@ func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interf
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SyncRequest)
|
||||
func _Query_Allocate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AllocateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(QueryServer).Sync(ctx, in)
|
||||
return srv.(QueryServer).Allocate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Query_Sync_FullMethodName,
|
||||
FullMethod: Query_Allocate_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(QueryServer).Sync(ctx, req.(*SyncRequest))
|
||||
return srv.(QueryServer).Allocate(ctx, req.(*AllocateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Query_SyncInitial_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SyncInitialRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(QueryServer).SyncInitial(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Query_SyncInitial_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(QueryServer).SyncInitial(ctx, req.(*SyncInitialRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Query_SyncCurrent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SyncCurrentRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(QueryServer).SyncCurrent(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Query_SyncCurrent_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(QueryServer).SyncCurrent(ctx, req.(*SyncCurrentRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@ -184,8 +258,16 @@ var Query_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _Query_Schema_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Sync",
|
||||
Handler: _Query_Sync_Handler,
|
||||
MethodName: "Allocate",
|
||||
Handler: _Query_Allocate_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SyncInitial",
|
||||
Handler: _Query_SyncInitial_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SyncCurrent",
|
||||
Handler: _Query_SyncCurrent_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1191,7 +1191,7 @@ func GetDefaultBypassFeeMessages() []string {
|
||||
sdk.MsgTypeURL(&ibcchanneltypes.MsgChannelOpenConfirm{}),
|
||||
sdk.MsgTypeURL(&ibcchanneltypes.MsgChannelOpenAck{}),
|
||||
sdk.MsgTypeURL(&vaulttypes.MsgAllocateVault{}),
|
||||
sdk.MsgTypeURL(&didtypes.MsgRegisterController{}),
|
||||
sdk.MsgTypeURL(&didtypes.MsgLinkAuthentication{}),
|
||||
}
|
||||
}
|
||||
|
||||
|
4
buf.work.yaml
Normal file
4
buf.work.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
version: v1
|
||||
directories:
|
||||
- proto
|
||||
- third_party/proto
|
@ -11,8 +11,8 @@ import (
|
||||
|
||||
func main() {
|
||||
s := echo.New()
|
||||
s.Use(ctx.SessionMiddleware)
|
||||
routes.RegisterProxyViews(s)
|
||||
routes.RegisterProxyAPI(s)
|
||||
s.Use(ctx.HighwaySessionMiddleware)
|
||||
routes.RegisterGatewayViews(s)
|
||||
routes.RegisterGatewayAPI(s)
|
||||
workers.Serve(s)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
name = "sonr-id"
|
||||
main = "./cmd/hway/build/worker.mjs"
|
||||
main = "./build/worker.mjs"
|
||||
compatibility_date = "2024-10-07"
|
||||
|
||||
routes = [{ pattern = "sonr.id", custom_domain = true }]
|
||||
|
||||
[build]
|
||||
command = "make hway-build"
|
||||
command = "task hway:build"
|
31
devbox.json
31
devbox.json
@ -1,6 +1,11 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
|
||||
"packages": ["go@1.22", "bun@latest", "ipfs@latest", "templ@latest"],
|
||||
"packages": [
|
||||
"go@1.22",
|
||||
"bun@latest",
|
||||
"ipfs@latest",
|
||||
"templ@latest"
|
||||
],
|
||||
"env": {
|
||||
"GOPATH": "$HOME/go",
|
||||
"PATH": "./build:$HOME/go/bin:$PATH",
|
||||
@ -20,18 +25,18 @@
|
||||
},
|
||||
"shell": {
|
||||
"scripts": {
|
||||
"build:docker": ["make local-image"],
|
||||
"build:hway": ["make hway-build"],
|
||||
"build:nebula": ["make nebula-build"],
|
||||
"build:motr": ["make motr-build"],
|
||||
"build:sonrd": ["make motr-build", "make build"],
|
||||
"build": ["make motr-build", "make build", "make hway-build"],
|
||||
"gen:proto": ["rm -rf ./pkg/nebula/node_modules", "make proto-gen"],
|
||||
"gen:pkl": ["make gen-pkl"],
|
||||
"gen:templ": ["make gen-templ"],
|
||||
"start": ["process-compose up -f ./deploy/process-compose.yaml"],
|
||||
"stop": ["process-compose down -f ./deploy/process-compose.yaml"],
|
||||
"start:testnet": ["make sh-testnet"]
|
||||
"gen:pkl": [
|
||||
"make gen-pkl"
|
||||
],
|
||||
"gen:templ": [
|
||||
"make gen-templ"
|
||||
],
|
||||
"start": [
|
||||
"process-compose up -f ./deploy/process-compose.yaml"
|
||||
],
|
||||
"stop": [
|
||||
"process-compose down -f ./deploy/process-compose.yaml"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
go.mod
4
go.mod
@ -66,14 +66,13 @@ require (
|
||||
github.com/go-webauthn/webauthn v0.10.2
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/sessions v1.4.0
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/ipfs/boxo v0.21.0
|
||||
github.com/ipfs/kubo v0.29.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/nlepage/go-js-promise v1.0.0
|
||||
github.com/onsonr/crypto v1.32.0
|
||||
github.com/onsonr/crypto v1.33.0
|
||||
github.com/segmentio/ksuid v1.0.4
|
||||
github.com/spf13/cast v1.6.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
@ -183,7 +182,6 @@ require (
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.2 // indirect
|
||||
github.com/gorilla/handlers v1.5.2 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||
|
8
go.sum
8
go.sum
@ -1375,10 +1375,6 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
|
||||
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
@ -1833,8 +1829,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/onsonr/crypto v1.32.0 h1:3XxItjoYg4vLuTU7uvpbIl/MTk2tb6L43SSO9RFcEXc=
|
||||
github.com/onsonr/crypto v1.32.0/go.mod h1:NSfeCO6XoyQeSDEp6Jy42UGG5047GvzG6lW9lRnjrR0=
|
||||
github.com/onsonr/crypto v1.33.0 h1:K0KgEQXrzppw/nPXn1swY1a7oUmMdQGcLycuipoqjqM=
|
||||
github.com/onsonr/crypto v1.33.0/go.mod h1:NSfeCO6XoyQeSDEp6Jy42UGG5047GvzG6lW9lRnjrR0=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||
|
@ -1,95 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"gopkg.in/macaroon.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
OriginMacroonCaveat MacroonCaveat = "origin"
|
||||
ScopesMacroonCaveat MacroonCaveat = "scopes"
|
||||
SubjectMacroonCaveat MacroonCaveat = "subject"
|
||||
ExpMacroonCaveat MacroonCaveat = "exp"
|
||||
TokenMacroonCaveat MacroonCaveat = "token"
|
||||
)
|
||||
|
||||
var MacroonCaveats = []MacroonCaveat{OriginMacroonCaveat, ScopesMacroonCaveat, SubjectMacroonCaveat, ExpMacroonCaveat, TokenMacroonCaveat}
|
||||
|
||||
type MacroonCaveat string
|
||||
|
||||
func (c MacroonCaveat) Equal(other string) bool {
|
||||
return string(c) == other
|
||||
}
|
||||
|
||||
func (c MacroonCaveat) String() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func (c MacroonCaveat) Verify(value string) error {
|
||||
switch c {
|
||||
case OriginMacroonCaveat:
|
||||
return nil
|
||||
case ScopesMacroonCaveat:
|
||||
return nil
|
||||
case SubjectMacroonCaveat:
|
||||
return nil
|
||||
case ExpMacroonCaveat:
|
||||
// Check if the expiration time is still valid
|
||||
exp, err := time.Parse(time.RFC3339, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if time.Now().After(exp) {
|
||||
return fmt.Errorf("expired")
|
||||
}
|
||||
return nil
|
||||
case TokenMacroonCaveat:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unknown caveat: %s", c)
|
||||
}
|
||||
}
|
||||
|
||||
func MacaroonMiddleware(secretKeyStr string, location string) echo.MiddlewareFunc {
|
||||
secretKey := []byte(secretKeyStr)
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// Extract the macaroon from the Authorization header
|
||||
auth := c.Request().Header.Get("Authorization")
|
||||
if auth == "" {
|
||||
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Missing Authorization header"})
|
||||
}
|
||||
|
||||
// Decode the macaroon
|
||||
mac, err := macaroon.Base64Decode([]byte(auth))
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid macaroon encoding"})
|
||||
}
|
||||
|
||||
token, err := macaroon.New(secretKey, mac, location, macaroon.LatestVersion)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid macaroon"})
|
||||
}
|
||||
|
||||
// Verify the macaroon
|
||||
err = token.Verify(secretKey, func(caveat string) error {
|
||||
for _, c := range MacroonCaveats {
|
||||
if c.String() == caveat {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil // Return nil if the caveat is valid
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Invalid macaroon"})
|
||||
}
|
||||
|
||||
// Macaroon is valid, proceed to the next handler
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
//go:build js && wasm
|
||||
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"syscall/js"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type BroadcastContext struct {
|
||||
echo.Context
|
||||
Channel js.Value
|
||||
}
|
||||
|
||||
func (c *BroadcastContext) BroadcastMessage(message string) {
|
||||
c.Channel.Call("postMessage", message)
|
||||
}
|
||||
|
||||
type JSHandler func(this js.Value, args []js.Value) interface{}
|
||||
|
||||
func UseBroadcastChannel(channelName string, handler JSHandler) echo.MiddlewareFunc {
|
||||
var channel js.Value
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
if channel.IsUndefined() {
|
||||
channel = js.Global().Get("BroadcastChannel").New(channelName)
|
||||
channel.Call("addEventListener", "message", handler)
|
||||
}
|
||||
|
||||
cc := &BroadcastContext{
|
||||
Context: c,
|
||||
Channel: channel,
|
||||
}
|
||||
return next(cc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PostBroadcastMessage(c echo.Context, message string) {
|
||||
cc := c.(*BroadcastContext)
|
||||
cc.BroadcastMessage(message)
|
||||
}
|
30
internal/ctx/cookies.go
Normal file
30
internal/ctx/cookies.go
Normal file
@ -0,0 +1,30 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/segmentio/ksuid"
|
||||
)
|
||||
|
||||
type CookieKey string
|
||||
|
||||
const (
|
||||
CookieKeySessionID CookieKey = "session.id"
|
||||
CookieKeySonrAddr CookieKey = "sonr.addr"
|
||||
CookieKeySonrDID CookieKey = "sonr.did"
|
||||
CookieKeyVaultCID CookieKey = "vault.cid"
|
||||
CookieKeyVaultSchema CookieKey = "vault.schema"
|
||||
)
|
||||
|
||||
func (c CookieKey) String() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func GetSessionID(c echo.Context) string {
|
||||
// Attempt to read the session ID from the "session" cookie
|
||||
sessionID, err := ReadCookie(c, CookieKeySessionID)
|
||||
if err != nil {
|
||||
// Generate a new KSUID if the session cookie is missing or invalid
|
||||
WriteCookie(c, CookieKeySessionID, ksuid.New().String())
|
||||
}
|
||||
return sessionID
|
||||
}
|
77
internal/ctx/ctx_dwn.go
Normal file
77
internal/ctx/ctx_dwn.go
Normal file
@ -0,0 +1,77 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
dwngen "github.com/onsonr/sonr/internal/dwn/gen"
|
||||
)
|
||||
|
||||
type DWNContext struct {
|
||||
echo.Context
|
||||
|
||||
// Defaults
|
||||
id string // Generated ksuid http cookie; Initialized on first request
|
||||
}
|
||||
|
||||
func (s *DWNContext) HasAuthorization() bool {
|
||||
v := ReadHeader(s.Context, HeaderAuthorization)
|
||||
return v != ""
|
||||
}
|
||||
|
||||
func (s *DWNContext) ID() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *DWNContext) Address() string {
|
||||
v, err := ReadCookie(s.Context, CookieKeySonrAddr)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (s *DWNContext) IPFSGatewayURL() string {
|
||||
return ReadHeader(s.Context, HeaderIPFSGatewayURL)
|
||||
}
|
||||
|
||||
func (s *DWNContext) ChainID() string {
|
||||
return ReadHeader(s.Context, HeaderSonrChainID)
|
||||
}
|
||||
|
||||
func (s *DWNContext) Schema() *dwngen.Schema {
|
||||
v, err := ReadCookie(s.Context, CookieKeyVaultSchema)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var schema dwngen.Schema
|
||||
err = json.Unmarshal([]byte(v), &schema)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &schema
|
||||
}
|
||||
|
||||
func GetDWNContext(c echo.Context) (*DWNContext, error) {
|
||||
ctx, ok := c.(*DWNContext)
|
||||
if !ok {
|
||||
return nil, echo.NewHTTPError(http.StatusInternalServerError, "DWN Context not found")
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// HighwaySessionMiddleware establishes a Session Cookie.
|
||||
func DWNSessionMiddleware(config *dwngen.Config) echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
sessionID := GetSessionID(c)
|
||||
injectConfig(c, config)
|
||||
cc := &DWNContext{
|
||||
Context: c,
|
||||
id: sessionID,
|
||||
}
|
||||
return next(cc)
|
||||
}
|
||||
}
|
||||
}
|
38
internal/ctx/ctx_hway.go
Normal file
38
internal/ctx/ctx_hway.go
Normal file
@ -0,0 +1,38 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type HwayContext struct {
|
||||
echo.Context
|
||||
|
||||
// Defaults
|
||||
id string // Generated ksuid http cookie; Initialized on first request
|
||||
}
|
||||
|
||||
func (s *HwayContext) ID() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func GetHWAYContext(c echo.Context) (*HwayContext, error) {
|
||||
ctx, ok := c.(*HwayContext)
|
||||
if !ok {
|
||||
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Highway Context not found")
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// HighwaySessionMiddleware establishes a Session Cookie.
|
||||
func HighwaySessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
sessionID := GetSessionID(c)
|
||||
cc := &HwayContext{
|
||||
Context: c,
|
||||
id: sessionID,
|
||||
}
|
||||
return next(cc)
|
||||
}
|
||||
}
|
21
internal/ctx/ctx_sonr.go
Normal file
21
internal/ctx/ctx_sonr.go
Normal file
@ -0,0 +1,21 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
type SonrContext struct {
|
||||
sdk.Context
|
||||
}
|
||||
|
||||
func GetSonrCTX(ctx sdk.Context) *SonrContext {
|
||||
return &SonrContext{ctx}
|
||||
}
|
||||
|
||||
func (s *SonrContext) GetBlockExpiration(duration time.Duration) int64 {
|
||||
blockTime := s.BlockTime()
|
||||
avgBlockTime := float64(blockTime.Sub(blockTime).Seconds())
|
||||
return int64(duration.Seconds() / avgBlockTime)
|
||||
}
|
@ -1,68 +1,37 @@
|
||||
package ctx
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Request Headers │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
type RequestHeaders struct {
|
||||
CacheControl *string `header:"Cache-Control"`
|
||||
DeviceMemory *string `header:"Device-Memory"`
|
||||
From *string `header:"From"`
|
||||
Host *string `header:"Host"`
|
||||
Referer *string `header:"Referer"`
|
||||
UserAgent *string `header:"User-Agent"`
|
||||
ViewportWidth *string `header:"Viewport-Width"`
|
||||
Width *string `header:"Width"`
|
||||
"github.com/labstack/echo/v4"
|
||||
dwngen "github.com/onsonr/sonr/internal/dwn/gen"
|
||||
)
|
||||
|
||||
// HTMX Specific
|
||||
HXBoosted *string `header:"HX-Boosted"`
|
||||
HXCurrentURL *string `header:"HX-Current-URL"`
|
||||
HXHistoryRestoreRequest *string `header:"HX-History-Restore-Request"`
|
||||
HXPrompt *string `header:"HX-Prompt"`
|
||||
HXRequest *string `header:"HX-Request"`
|
||||
HXTarget *string `header:"HX-Target"`
|
||||
HXTriggerName *string `header:"HX-Trigger-Name"`
|
||||
HXTrigger *string `header:"HX-Trigger"`
|
||||
type HeaderKey string
|
||||
|
||||
const (
|
||||
HeaderAuthorization HeaderKey = "Authorization"
|
||||
|
||||
HeaderIPFSGatewayURL HeaderKey = "X-IPFS-Gateway"
|
||||
HeaderSonrChainID HeaderKey = "X-Sonr-ChainID"
|
||||
HeaderSonrKeyshare HeaderKey = "X-Sonr-Keyshare"
|
||||
)
|
||||
|
||||
func (h HeaderKey) String() string {
|
||||
return string(h)
|
||||
}
|
||||
|
||||
type ProtectedRequestHeaders struct {
|
||||
Authorization *string `header:"Authorization"`
|
||||
Forwarded *string `header:"Forwarded"`
|
||||
Link *string `header:"Link"`
|
||||
PermissionsPolicy *string `header:"Permissions-Policy"`
|
||||
ProxyAuthorization *string `header:"Proxy-Authorization"`
|
||||
WWWAuthenticate *string `header:"WWW-Authenticate"`
|
||||
}
|
||||
func injectConfig(c echo.Context, config *dwngen.Config) {
|
||||
WriteHeader(c, HeaderIPFSGatewayURL, config.IpfsGatewayUrl)
|
||||
WriteHeader(c, HeaderSonrChainID, config.SonrChainId)
|
||||
WriteHeader(c, HeaderSonrKeyshare, config.MotrKeyshare)
|
||||
WriteCookie(c, CookieKeySonrAddr, config.MotrAddress)
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Response Headers │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
schemaBz, err := json.Marshal(config.VaultSchema)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
type ResponseHeaders struct {
|
||||
// HTMX Specific
|
||||
HXLocation *string `header:"HX-Location"`
|
||||
HXPushURL *string `header:"HX-Push-Url"`
|
||||
HXRedirect *string `header:"HX-Redirect"`
|
||||
HXRefresh *string `header:"HX-Refresh"`
|
||||
HXReplaceURL *string `header:"HX-Replace-Url"`
|
||||
HXReswap *string `header:"HX-Reswap"`
|
||||
HXRetarget *string `header:"HX-Retarget"`
|
||||
HXReselect *string `header:"HX-Reselect"`
|
||||
HXTrigger *string `header:"HX-Trigger"`
|
||||
HXTriggerAfterSettle *string `header:"HX-Trigger-After-Settle"`
|
||||
HXTriggerAfterSwap *string `header:"HX-Trigger-After-Swap"`
|
||||
}
|
||||
|
||||
type ProtectedResponseHeaders struct {
|
||||
AcceptCH *string `header:"Accept-CH"`
|
||||
AccessControlAllowCredentials *string `header:"Access-Control-Allow-Credentials"`
|
||||
AccessControlAllowHeaders *string `header:"Access-Control-Allow-Headers"`
|
||||
AccessControlAllowMethods *string `header:"Access-Control-Allow-Methods"`
|
||||
AccessControlExposeHeaders *string `header:"Access-Control-Expose-Headers"`
|
||||
AccessControlRequestHeaders *string `header:"Access-Control-Request-Headers"`
|
||||
ContentSecurityPolicy *string `header:"Content-Security-Policy"`
|
||||
CrossOriginEmbedderPolicy *string `header:"Cross-Origin-Embedder-Policy"`
|
||||
PermissionsPolicy *string `header:"Permissions-Policy"`
|
||||
ProxyAuthorization *string `header:"Proxy-Authorization"`
|
||||
WWWAuthenticate *string `header:"WWW-Authenticate"`
|
||||
WriteCookie(c, CookieKeyVaultSchema, string(schemaBz))
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func RenderTempl(c echo.Context, cmp templ.Component) error {
|
||||
// Create a buffer to store the rendered HTML
|
||||
buf := &bytes.Buffer{}
|
||||
// Render the component to the buffer
|
||||
err := cmp.Render(c.Request().Context(), buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the content type
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML)
|
||||
|
||||
// Write the buffered content to the response
|
||||
_, err = c.Response().Write(buf.Bytes())
|
||||
return err
|
||||
}
|
35
internal/ctx/request.go
Normal file
35
internal/ctx/request.go
Normal file
@ -0,0 +1,35 @@
|
||||
package ctx
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Request Headers │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
type RequestHeaders struct {
|
||||
CacheControl *string `header:"Cache-Control"`
|
||||
DeviceMemory *string `header:"Device-Memory"`
|
||||
From *string `header:"From"`
|
||||
Host *string `header:"Host"`
|
||||
Referer *string `header:"Referer"`
|
||||
UserAgent *string `header:"User-Agent"`
|
||||
ViewportWidth *string `header:"Viewport-Width"`
|
||||
Width *string `header:"Width"`
|
||||
|
||||
// HTMX Specific
|
||||
HXBoosted *string `header:"HX-Boosted"`
|
||||
HXCurrentURL *string `header:"HX-Current-URL"`
|
||||
HXHistoryRestoreRequest *string `header:"HX-History-Restore-Request"`
|
||||
HXPrompt *string `header:"HX-Prompt"`
|
||||
HXRequest *string `header:"HX-Request"`
|
||||
HXTarget *string `header:"HX-Target"`
|
||||
HXTriggerName *string `header:"HX-Trigger-Name"`
|
||||
HXTrigger *string `header:"HX-Trigger"`
|
||||
}
|
||||
|
||||
type ProtectedRequestHeaders struct {
|
||||
Authorization *string `header:"Authorization"`
|
||||
Forwarded *string `header:"Forwarded"`
|
||||
Link *string `header:"Link"`
|
||||
PermissionsPolicy *string `header:"Permissions-Policy"`
|
||||
ProxyAuthorization *string `header:"Proxy-Authorization"`
|
||||
WWWAuthenticate *string `header:"WWW-Authenticate"`
|
||||
}
|
38
internal/ctx/response.go
Normal file
38
internal/ctx/response.go
Normal file
@ -0,0 +1,38 @@
|
||||
package ctx
|
||||
|
||||
import "github.com/go-webauthn/webauthn/protocol"
|
||||
|
||||
type WebBytes = protocol.URLEncodedBase64
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Response Headers │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
type ResponseHeaders struct {
|
||||
// HTMX Specific
|
||||
HXLocation *string `header:"HX-Location"`
|
||||
HXPushURL *string `header:"HX-Push-Url"`
|
||||
HXRedirect *string `header:"HX-Redirect"`
|
||||
HXRefresh *string `header:"HX-Refresh"`
|
||||
HXReplaceURL *string `header:"HX-Replace-Url"`
|
||||
HXReswap *string `header:"HX-Reswap"`
|
||||
HXRetarget *string `header:"HX-Retarget"`
|
||||
HXReselect *string `header:"HX-Reselect"`
|
||||
HXTrigger *string `header:"HX-Trigger"`
|
||||
HXTriggerAfterSettle *string `header:"HX-Trigger-After-Settle"`
|
||||
HXTriggerAfterSwap *string `header:"HX-Trigger-After-Swap"`
|
||||
}
|
||||
|
||||
type ProtectedResponseHeaders struct {
|
||||
AcceptCH *string `header:"Accept-CH"`
|
||||
AccessControlAllowCredentials *string `header:"Access-Control-Allow-Credentials"`
|
||||
AccessControlAllowHeaders *string `header:"Access-Control-Allow-Headers"`
|
||||
AccessControlAllowMethods *string `header:"Access-Control-Allow-Methods"`
|
||||
AccessControlExposeHeaders *string `header:"Access-Control-Expose-Headers"`
|
||||
AccessControlRequestHeaders *string `header:"Access-Control-Request-Headers"`
|
||||
ContentSecurityPolicy *string `header:"Content-Security-Policy"`
|
||||
CrossOriginEmbedderPolicy *string `header:"Cross-Origin-Embedder-Policy"`
|
||||
PermissionsPolicy *string `header:"Permissions-Policy"`
|
||||
ProxyAuthorization *string `header:"Proxy-Authorization"`
|
||||
WWWAuthenticate *string `header:"WWW-Authenticate"`
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/segmentio/ksuid"
|
||||
)
|
||||
|
||||
var store sessions.Store
|
||||
|
||||
type ctxKeySessionID struct{}
|
||||
|
||||
// SessionMiddleware establishes a Session Cookie.
|
||||
func SessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
store = sessions.NewCookieStore([]byte("SESSION_KEY"))
|
||||
return func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
|
||||
// Attempt to read the session ID from the "session" cookie
|
||||
sessionID, err := readSessionIDFromCookie(c)
|
||||
if err != nil {
|
||||
// Generate a new KSUID if the session cookie is missing or invalid
|
||||
sessionID = ksuid.New().String()
|
||||
// Write the new session ID to the "session" cookie
|
||||
err = writeSessionIDToCookie(c, sessionID)
|
||||
if err != nil {
|
||||
return c.JSON(
|
||||
http.StatusInternalServerError,
|
||||
map[string]string{"error": "Failed to set session cookie"},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Inject the session ID into the context
|
||||
ctx = context.WithValue(ctx, ctxKeySessionID{}, sessionID)
|
||||
// Update the request with the new context
|
||||
c.SetRequest(c.Request().WithContext(ctx))
|
||||
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
||||
func buildSession(c echo.Context, id string) *Session {
|
||||
return &Session{
|
||||
ID: id,
|
||||
Origin: getOrigin(c.Request().Header.Get("Host")),
|
||||
UserAgent: c.Request().Header.Get("Sec-Ch-Ua"),
|
||||
Platform: c.Request().Header.Get("Sec-Ch-Ua-Platform"),
|
||||
Address: c.Request().Header.Get("X-Sonr-Address"),
|
||||
ChainID: "",
|
||||
}
|
||||
}
|
||||
|
||||
func getOrigin(o string) string {
|
||||
if o == "" {
|
||||
return ""
|
||||
}
|
||||
u, err := url.Parse(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return u.Hostname()
|
||||
}
|
||||
|
||||
func getSessionID(ctx context.Context) (string, error) {
|
||||
sessionID, ok := ctx.Value(ctxKeySessionID{}).(string)
|
||||
if !ok || sessionID == "" {
|
||||
return "", errors.New("session ID not found in context")
|
||||
}
|
||||
return sessionID, nil
|
||||
}
|
||||
|
||||
func readSessionIDFromCookie(c echo.Context) (string, error) {
|
||||
cookie, err := c.Cookie("session")
|
||||
if err != nil {
|
||||
// Cookie not found or other error
|
||||
return "", err
|
||||
}
|
||||
if cookie == nil || cookie.Value == "" {
|
||||
// Cookie is empty
|
||||
return "", http.ErrNoCookie
|
||||
}
|
||||
return cookie.Value, nil
|
||||
}
|
||||
|
||||
func writeSessionIDToCookie(c echo.Context, sessionID string) error {
|
||||
cookie := &http.Cookie{
|
||||
Name: "session",
|
||||
Value: sessionID,
|
||||
Expires: time.Now().Add(24 * time.Hour),
|
||||
HttpOnly: true,
|
||||
Path: "/",
|
||||
// Add Secure and SameSite attributes as needed
|
||||
}
|
||||
c.SetCookie(cookie)
|
||||
return nil
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
type AuthState string
|
||||
|
||||
const (
|
||||
Visitor AuthState = "visitor"
|
||||
Authenticated AuthState = "authenticated"
|
||||
Expired AuthState = "expired"
|
||||
|
||||
PendingCredentials AuthState = "pending_credentials"
|
||||
PendingAssertion AuthState = "pending_assertion"
|
||||
)
|
||||
|
||||
func (s AuthState) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func GetAuthState(c echo.Context) AuthState {
|
||||
vals := c.Request().Header.Values("Authorization")
|
||||
if len(vals) == 0 {
|
||||
return Visitor
|
||||
}
|
||||
s := AuthState(c.Request().Header.Get("Authorization"))
|
||||
return s
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type WebBytes = protocol.URLEncodedBase64
|
||||
|
||||
type Session struct {
|
||||
// Defaults
|
||||
ID string // Generated ksuid http cookie; Initialized on first request
|
||||
Origin string // Webauthn mapping to Relaying Party ID; Initialized on first request
|
||||
UserAgent string
|
||||
Platform string
|
||||
|
||||
// Initialization
|
||||
Address string // Webauthn mapping to User ID; Supplied by DWN frontend
|
||||
ChainID string // Macaroon mapping to location; Supplied by DWN frontend
|
||||
|
||||
Subject string // Webauthn mapping to User Displayable Name; Supplied by DWN frontend
|
||||
|
||||
// Authentication
|
||||
challenge WebBytes // Webauthn mapping to Challenge; Per session based on origin
|
||||
}
|
||||
|
||||
func (s *Session) GetChallenge(subject string) (WebBytes, error) {
|
||||
// Check if challenge is already set and subject matches
|
||||
if s.Subject != "" && s.Subject != subject {
|
||||
return nil, errors.New("challenge already set, and subject does not match")
|
||||
} else if s.Subject == "" {
|
||||
s.Subject = subject
|
||||
} else {
|
||||
return s.challenge, nil
|
||||
}
|
||||
|
||||
if s.challenge == nil {
|
||||
chl, err := protocol.CreateChallenge()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.challenge = chl
|
||||
}
|
||||
return s.challenge, nil
|
||||
}
|
||||
|
||||
func (s *Session) ValidateChallenge(challenge WebBytes, subject string) error {
|
||||
if s.challenge == nil {
|
||||
return nil
|
||||
}
|
||||
if s.challenge.String() != challenge.String() {
|
||||
return fmt.Errorf("invalid challenge")
|
||||
}
|
||||
s.Subject = subject
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetSession(c echo.Context) *Session {
|
||||
id, _ := getSessionID(c.Request().Context())
|
||||
return buildSession(c, id)
|
||||
}
|
||||
|
||||
func SetAddress(c echo.Context, address string) *Session {
|
||||
// Write address to X-Sonr-Address header
|
||||
c.Response().Header().Set("X-Sonr-Address", address)
|
||||
return buildSession(c, "")
|
||||
}
|
73
internal/ctx/utils.go
Normal file
73
internal/ctx/utils.go
Normal file
@ -0,0 +1,73 @@
|
||||
package ctx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Template Rendering │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
func RenderTempl(c echo.Context, cmp templ.Component) error {
|
||||
// Create a buffer to store the rendered HTML
|
||||
buf := &bytes.Buffer{}
|
||||
// Render the component to the buffer
|
||||
err := cmp.Render(c.Request().Context(), buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the content type
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML)
|
||||
|
||||
// Write the buffered content to the response
|
||||
_, err = c.Response().Write(buf.Bytes())
|
||||
return err
|
||||
}
|
||||
|
||||
// ╭──────────────────────────────────────────────────────────╮
|
||||
// │ Cookie Management │
|
||||
// ╰──────────────────────────────────────────────────────────╯
|
||||
|
||||
func ReadCookie(c echo.Context, key CookieKey) (string, error) {
|
||||
cookie, err := c.Cookie(key.String())
|
||||
if err != nil {
|
||||
// Cookie not found or other error
|
||||
return "", err
|
||||
}
|
||||
if cookie == nil || cookie.Value == "" {
|
||||
// Cookie is empty
|
||||
return "", http.ErrNoCookie
|
||||
}
|
||||
return cookie.Value, nil
|
||||
}
|
||||
|
||||
func WriteCookie(c echo.Context, key CookieKey, value string) error {
|
||||
cookie := &http.Cookie{
|
||||
Name: key.String(),
|
||||
Value: value,
|
||||
Expires: time.Now().Add(24 * time.Hour),
|
||||
HttpOnly: true,
|
||||
Path: "/",
|
||||
// Add Secure and SameSite attributes as needed
|
||||
}
|
||||
c.SetCookie(cookie)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ╭────────────────────────────────────────────────────────╮
|
||||
// │ HTTP Headers │
|
||||
// ╰────────────────────────────────────────────────────────╯
|
||||
|
||||
func WriteHeader(c echo.Context, key HeaderKey, value string) {
|
||||
c.Response().Header().Set(key.String(), value)
|
||||
}
|
||||
|
||||
func ReadHeader(c echo.Context, key HeaderKey) string {
|
||||
return c.Response().Header().Get(key.String())
|
||||
}
|
Binary file not shown.
@ -2,10 +2,18 @@ package dwn
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ipfs/boxo/files"
|
||||
"github.com/onsonr/sonr/internal/dwn/gen"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/index"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/vaultindex"
|
||||
)
|
||||
|
||||
const (
|
||||
FileNameAppWASM = "app.wasm"
|
||||
FileNameConfigJSON = "dwn.json"
|
||||
FileNameIndexHTML = "index.html"
|
||||
FileNameWorkerJS = "sw.js"
|
||||
)
|
||||
|
||||
//go:embed app.wasm
|
||||
@ -14,21 +22,21 @@ var dwnWasmData []byte
|
||||
//go:embed sw.js
|
||||
var swJSData []byte
|
||||
|
||||
var (
|
||||
dwnWasmFile = files.NewBytesFile(dwnWasmData)
|
||||
swJSFile = files.NewBytesFile(swJSData)
|
||||
)
|
||||
|
||||
// NewVaultDirectory creates a new directory with the default files
|
||||
func NewVaultDirectory(cnfg *gen.Config) (files.Node, error) {
|
||||
idxFile, err := index.BuildFile(cnfg)
|
||||
idxFile, err := vaultindex.BuildFile(cnfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cnfgBz, err := json.Marshal(cnfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileMap := map[string]files.Node{
|
||||
"sw.js": swJSFile,
|
||||
"app.wasm": dwnWasmFile,
|
||||
"index.html": idxFile,
|
||||
FileNameAppWASM: files.NewBytesFile(dwnWasmData),
|
||||
FileNameConfigJSON: files.NewBytesFile(cnfgBz),
|
||||
FileNameIndexHTML: idxFile,
|
||||
FileNameWorkerJS: files.NewBytesFile(swJSData),
|
||||
}
|
||||
return files.NewMapDirectory(fileMap), nil
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package dwn
|
||||
package fetch
|
||||
|
||||
import (
|
||||
"bytes"
|
@ -2,13 +2,17 @@
|
||||
package gen
|
||||
|
||||
type Config struct {
|
||||
Ipfs *IPFS `pkl:"ipfs" json:"ipfs,omitempty"`
|
||||
IpfsGatewayUrl string `pkl:"ipfsGatewayUrl" json:"ipfsGatewayUrl,omitempty"`
|
||||
|
||||
Sonr *Sonr `pkl:"sonr" json:"sonr,omitempty"`
|
||||
MotrKeyshare string `pkl:"motrKeyshare" json:"motrKeyshare,omitempty"`
|
||||
|
||||
Motr *Motr `pkl:"motr" json:"motr,omitempty"`
|
||||
MotrAddress string `pkl:"motrAddress" json:"motrAddress,omitempty"`
|
||||
|
||||
Schema *Schema `pkl:"schema" json:"schema,omitempty"`
|
||||
SonrApiUrl string `pkl:"sonrApiUrl" json:"sonrApiUrl,omitempty"`
|
||||
|
||||
ProxyUrl string `pkl:"proxyUrl" json:"proxyUrl,omitempty"`
|
||||
SonrRpcUrl string `pkl:"sonrRpcUrl" json:"sonrRpcUrl,omitempty"`
|
||||
|
||||
SonrChainId string `pkl:"sonrChainId" json:"sonrChainId,omitempty"`
|
||||
|
||||
VaultSchema *Schema `pkl:"vaultSchema" json:"vaultSchema,omitempty"`
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
// Code generated from Pkl module `dwngen`. DO NOT EDIT.
|
||||
package gen
|
||||
|
||||
type IPFS struct {
|
||||
ApiUrl string `pkl:"apiUrl" json:"apiUrl,omitempty"`
|
||||
|
||||
GatewayUrl string `pkl:"gatewayUrl" json:"gatewayUrl,omitempty"`
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
// Code generated from Pkl module `dwngen`. DO NOT EDIT.
|
||||
package gen
|
||||
|
||||
type Motr struct {
|
||||
Keyshare string `pkl:"keyshare" json:"keyshare,omitempty"`
|
||||
|
||||
Address string `pkl:"address" json:"address,omitempty"`
|
||||
|
||||
Origin string `pkl:"origin" json:"origin,omitempty"`
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
// Code generated from Pkl module `dwngen`. DO NOT EDIT.
|
||||
package gen
|
||||
|
||||
type Sonr struct {
|
||||
ApiUrl string `pkl:"apiUrl" json:"apiUrl,omitempty"`
|
||||
|
||||
GrpcUrl string `pkl:"grpcUrl" json:"grpcUrl,omitempty"`
|
||||
|
||||
RpcUrl string `pkl:"rpcUrl" json:"rpcUrl,omitempty"`
|
||||
|
||||
WebSocketUrl string `pkl:"webSocketUrl" json:"webSocketUrl,omitempty"`
|
||||
|
||||
ChainId string `pkl:"chainId" json:"chainId,omitempty"`
|
||||
}
|
@ -6,8 +6,5 @@ import "github.com/apple/pkl-go/pkl"
|
||||
func init() {
|
||||
pkl.RegisterMapping("dwngen", Dwngen{})
|
||||
pkl.RegisterMapping("dwngen#Config", Config{})
|
||||
pkl.RegisterMapping("dwngen#IPFS", IPFS{})
|
||||
pkl.RegisterMapping("dwngen#Sonr", Sonr{})
|
||||
pkl.RegisterMapping("dwngen#Motr", Motr{})
|
||||
pkl.RegisterMapping("dwngen#Schema", Schema{})
|
||||
}
|
||||
|
@ -9,11 +9,13 @@ import (
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/internal/ctx"
|
||||
"github.com/onsonr/sonr/internal/dwn"
|
||||
"github.com/onsonr/sonr/internal/dwn/fetch"
|
||||
dwngen "github.com/onsonr/sonr/internal/dwn/gen"
|
||||
"github.com/onsonr/sonr/pkg/workers/routes"
|
||||
)
|
||||
|
||||
const FileNameConfigJSON = "dwn.json"
|
||||
|
||||
var config *dwngen.Config
|
||||
|
||||
func main() {
|
||||
@ -24,19 +26,19 @@ func main() {
|
||||
|
||||
// Setup HTTP server
|
||||
e := echo.New()
|
||||
e.Use(ctx.SessionMiddleware)
|
||||
routes.RegisterClientAPI(e)
|
||||
routes.RegisterClientViews(e)
|
||||
dwn.Serve(e)
|
||||
e.Use(ctx.DWNSessionMiddleware(config))
|
||||
routes.RegisterWebNodeAPI(e)
|
||||
routes.RegisterWebNodeViews(e)
|
||||
fetch.Serve(e)
|
||||
}
|
||||
|
||||
func loadDwnConfig() error {
|
||||
// Read dwn.json config
|
||||
dwnBz, err := os.ReadFile("dwn.json")
|
||||
dwnBz, err := os.ReadFile(FileNameConfigJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dwnConfig := &dwngen.Config{}
|
||||
dwnConfig := new(dwngen.Config)
|
||||
err = json.Unmarshal(dwnBz, dwnConfig)
|
||||
if err != nil {
|
||||
return err
|
@ -923,6 +923,40 @@ select{
|
||||
format("woff2");
|
||||
}
|
||||
|
||||
.container{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 640px){
|
||||
.container{
|
||||
max-width: 640px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
.container{
|
||||
max-width: 768px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px){
|
||||
.container{
|
||||
max-width: 1024px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px){
|
||||
.container{
|
||||
max-width: 1280px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1536px){
|
||||
.container{
|
||||
max-width: 1536px;
|
||||
}
|
||||
}
|
||||
|
||||
.motion-preset-slide-up{
|
||||
--motion-origin-translate-y: 25%;
|
||||
--motion-origin-opacity: 0;
|
||||
@ -1074,16 +1108,6 @@ select{
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
.-mx-6{
|
||||
margin-left: -1.5rem;
|
||||
margin-right: -1.5rem;
|
||||
}
|
||||
|
||||
.mx-6{
|
||||
margin-left: 1.5rem;
|
||||
margin-right: 1.5rem;
|
||||
}
|
||||
|
||||
.mx-auto{
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@ -2027,10 +2051,6 @@ select{
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.pt-12{
|
||||
padding-top: 3rem;
|
||||
}
|
||||
|
||||
.pt-2{
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
@ -2059,6 +2079,10 @@ select{
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.font-fancy{
|
||||
font-family: "ZT Bros Oskon 90s", sans-serif;
|
||||
}
|
||||
|
||||
.font-inter{
|
||||
font-family: Inter, sans-serif;
|
||||
}
|
||||
@ -2549,11 +2573,6 @@ select{
|
||||
mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px));
|
||||
}
|
||||
|
||||
.\[mask-image\:linear-gradient\(white_0\%\2c white_calc\(100\%-40px\)\2c _transparent_calc\(100\%-1px\)\)\]{
|
||||
-webkit-mask-image: linear-gradient(white 0%,white calc(100% - 40px), transparent calc(100% - 1px));
|
||||
mask-image: linear-gradient(white 0%,white calc(100% - 40px), transparent calc(100% - 1px));
|
||||
}
|
||||
|
||||
/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */
|
||||
|
||||
[x-cloak=""] {
|
||||
@ -3462,10 +3481,6 @@ input[type="search"]::-webkit-search-results-decoration {
|
||||
padding-bottom: 5rem;
|
||||
}
|
||||
|
||||
.md\:pt-20{
|
||||
padding-top: 5rem;
|
||||
}
|
||||
|
||||
.md\:pt-40{
|
||||
padding-top: 10rem;
|
||||
}
|
||||
|
15
pkg/nebula/assets/js/alpin-focus.min.js
vendored
Normal file
15
pkg/nebula/assets/js/alpin-focus.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,11 +0,0 @@
|
||||
package forms
|
||||
|
||||
templ BasicDetailsForm() {
|
||||
<div class="border rounded-lg shadow-sm bg-card text-zinc-900">
|
||||
<div class="flex flex-col space-y-1.5 p-6"></div>
|
||||
<div class="p-6 pt-0 space-y-2">
|
||||
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="name">Name</label><input type="text" id="name" placeholder="Adam Wathan" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
|
||||
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="username">Handle</label><input type="text" id="handle" placeholder="angelo.snr" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/internal/ctx"
|
||||
)
|
||||
|
||||
func AuthorizeRoute(c echo.Context) error {
|
||||
return ctx.RenderTempl(c, AuthorizeModal(c))
|
||||
}
|
||||
|
||||
func LoginRoute(c echo.Context) error {
|
||||
return ctx.RenderTempl(c, LoginModal(c))
|
||||
}
|
||||
|
||||
func RegisterRoute(c echo.Context) error {
|
||||
return ctx.RenderTempl(c, RegisterModal(c))
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package forms
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
templ AssertCredentialForm() {
|
||||
<div class="border rounded-lg shadow-sm bg-card text-zinc-900">
|
||||
<div class="flex flex-col space-y-1.5 p-6"></div>
|
||||
@ -9,3 +11,25 @@ templ AssertCredentialForm() {
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ NavigatorCredentialsGetAll(c echo.Context) {
|
||||
<script>
|
||||
navigator.credentials.getAll({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array(0),
|
||||
allowCredentials: [],
|
||||
timeout: 60000,
|
||||
userVerification: "discouraged",
|
||||
extensions: {
|
||||
|
||||
}
|
||||
},
|
||||
})
|
||||
.then((assertion) => {
|
||||
console.log("Assertion:", assertion);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
</script>
|
||||
}
|
@ -8,6 +8,8 @@ package forms
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func AssertCredentialForm() 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
|
||||
@ -37,4 +39,33 @@ func AssertCredentialForm() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func NavigatorCredentialsGetAll(c echo.Context) 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_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tnavigator.credentials.getAll({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tallowCredentials: [],\n\t\t\t\ttimeout: 60000,\n\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\textensions: {\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -1,5 +1,7 @@
|
||||
package forms
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
templ RegisterCredentialForm() {
|
||||
<div class="border rounded-lg shadow-sm bg-card text-zinc-900">
|
||||
<div class="flex flex-col space-y-1.5 p-6"></div>
|
||||
@ -9,3 +11,39 @@ templ RegisterCredentialForm() {
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ NavigatorCredentialsCreate(c echo.Context) {
|
||||
<script>
|
||||
function createCredential() {
|
||||
navigator.credentials.create({
|
||||
publicKey: {
|
||||
rp: {
|
||||
name: "Sonr",
|
||||
},
|
||||
user: {
|
||||
id: new Uint8Array(0),
|
||||
name: "Sonr",
|
||||
displayName: "Sonr",
|
||||
},
|
||||
challenge: new Uint8Array(0),
|
||||
pubKeyCredParams: [{
|
||||
type: "public-key",
|
||||
alg: -7,
|
||||
}],
|
||||
timeout: 60000,
|
||||
excludeCredentials: [],
|
||||
authenticatorSelection: {
|
||||
requireResidentKey: false,
|
||||
userVerification: "discouraged",
|
||||
},
|
||||
},
|
||||
})
|
||||
.then((assertion) => {
|
||||
console.log("Assertion:", assertion);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
@ -8,6 +8,8 @@ package forms
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func RegisterCredentialForm() 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
|
||||
@ -37,4 +39,33 @@ func RegisterCredentialForm() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func NavigatorCredentialsCreate(c echo.Context) 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_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\tfunction createCredential() {\n\t\tnavigator.credentials.create({\n\t\t\tpublicKey: {\n\t\t\t\trp: {\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tuser: {\n\t\t\t\t\tid: new Uint8Array(0),\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t\tdisplayName: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tpubKeyCredParams: [{\n\t\t\t\t\ttype: \"public-key\",\n\t\t\t\t\talg: -7,\n\t\t\t\t}],\n\t\t\t\ttimeout: 60000,\n\t\t\t\texcludeCredentials: [],\n\t\t\t\tauthenticatorSelection: {\n\t\t\t\t\trequireResidentKey: false,\n\t\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t\t}\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -0,0 +1,18 @@
|
||||
package forms
|
||||
|
||||
templ BasicDetailsForm() {
|
||||
<div class="border rounded-lg shadow-sm bg-card text-zinc-900">
|
||||
<div class="flex flex-col space-y-1.5 p-6"></div>
|
||||
@nameInput()
|
||||
@usernameInput()
|
||||
<div class="p-6 pt-0 space-y-2"></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ nameInput() {
|
||||
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="name">Name</label><input type="text" id="name" placeholder="Adam Wathan" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
|
||||
}
|
||||
|
||||
templ usernameInput() {
|
||||
<div class="space-y-1"><label class="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="username">Handle</label><input type="text" id="handle" placeholder="angelo.snr" class="flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50"/></div>
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package forms
|
||||
|
||||
//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 BasicDetailsForm() 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=\"border rounded-lg shadow-sm bg-card text-zinc-900\"><div class=\"flex flex-col space-y-1.5 p-6\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = nameInput().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = usernameInput().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"p-6 pt-0 space-y-2\"></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func nameInput() 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_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"name\">Name</label><input type=\"text\" id=\"name\" placeholder=\"Adam Wathan\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func usernameInput() 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 = templ_7745c5c3_Buffer.WriteString("<div class=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"username\">Handle</label><input type=\"text\" id=\"handle\" placeholder=\"angelo.snr\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -1,8 +1,8 @@
|
||||
package auth
|
||||
package authentication
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
)
|
||||
|
||||
@ -14,12 +14,12 @@ templ RegisterModal(c echo.Context) {
|
||||
|
||||
templ LoginModal(c echo.Context) {
|
||||
@styles.OpenModal("Account Registration", "Enter your account information below to create your account.") {
|
||||
@sections.RegisterStart()
|
||||
@sections.LoginStart()
|
||||
}
|
||||
}
|
||||
|
||||
templ AuthorizeModal(c echo.Context) {
|
||||
@styles.OpenModal("Account Registration", "Enter your account information below to create your account.") {
|
||||
@sections.RegisterStart()
|
||||
@sections.AuthorizeStart()
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package auth
|
||||
package authentication
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
@ -10,7 +10,7 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
)
|
||||
|
||||
@ -94,7 +94,7 @@ func LoginModal(c echo.Context) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = sections.RegisterStart().Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = sections.LoginStart().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -141,7 +141,7 @@ func AuthorizeModal(c echo.Context) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = sections.RegisterStart().Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = sections.AuthorizeStart().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
37
pkg/nebula/components/authentication/route.go
Normal file
37
pkg/nebula/components/authentication/route.go
Normal file
@ -0,0 +1,37 @@
|
||||
package authentication
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/internal/ctx"
|
||||
)
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ DWN Routes - Authentication │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
func CurrentViewRoute(c echo.Context) error {
|
||||
s, err := ctx.GetDWNContext(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Session ID: %s", s.ID())
|
||||
return ctx.RenderTempl(c, CurrentView(c))
|
||||
}
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Hway Routes - Authentication │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
func AuthorizeModalRoute(c echo.Context) error {
|
||||
return ctx.RenderTempl(c, AuthorizeModal(c))
|
||||
}
|
||||
|
||||
func LoginModalRoute(c echo.Context) error {
|
||||
return ctx.RenderTempl(c, LoginModal(c))
|
||||
}
|
||||
|
||||
func RegisterModalRoute(c echo.Context) error {
|
||||
return ctx.RenderTempl(c, RegisterModal(c))
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package sections
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
@ -9,7 +9,7 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
package sections
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
@ -9,7 +9,7 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
package sections
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
@ -9,7 +9,7 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/auth/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/authentication/forms"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
23
pkg/nebula/components/authentication/view.templ
Normal file
23
pkg/nebula/components/authentication/view.templ
Normal file
@ -0,0 +1,23 @@
|
||||
package authentication
|
||||
|
||||
import echo "github.com/labstack/echo/v4"
|
||||
|
||||
templ CurrentView(c echo.Context) {
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Current Account</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">
|
||||
<a href="/logout">Logout</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package forms
|
||||
package authentication
|
||||
|
||||
//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 BasicDetailsForm() templ.Component {
|
||||
import echo "github.com/labstack/echo/v4"
|
||||
|
||||
func CurrentView(c echo.Context) 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 {
|
||||
@ -29,7 +31,7 @@ func BasicDetailsForm() templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"border rounded-lg shadow-sm bg-card text-zinc-900\"><div class=\"flex flex-col space-y-1.5 p-6\"></div><div class=\"p-6 pt-0 space-y-2\"><div class=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"name\">Name</label><input type=\"text\" id=\"name\" placeholder=\"Adam Wathan\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div><div class=\"space-y-1\"><label class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\" for=\"username\">Handle</label><input type=\"text\" id=\"handle\" placeholder=\"angelo.snr\" class=\"flex w-full h-10 px-3 py-2 text-sm bg-white border rounded-md peer border-zinc-300 ring-offset-background placeholder:text-zinc-400 focus:border-zinc-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-400 disabled:cursor-not-allowed disabled:opacity-50\"></div></div></div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"container\"><div class=\"row\"><div class=\"col-md-12\"><div class=\"card\"><div class=\"card-header\"><h3 class=\"card-title\">Current Account</h3></div><div class=\"card-body\"><p class=\"card-text\"><a href=\"/logout\">Logout</a></p></div></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package home
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/onsonr/sonr/internal/ctx"
|
||||
)
|
||||
|
||||
func Route(c echo.Context) error {
|
||||
s := ctx.GetSession(c)
|
||||
log.Printf("Session ID: %s", s.ID)
|
||||
log.Printf("Session Origin: %s", s.Origin)
|
||||
log.Printf("Session Address: %s", s.Address)
|
||||
log.Printf("Session ChainID: %s", s.ChainID)
|
||||
return ctx.RenderTempl(c, View())
|
||||
}
|
@ -1,219 +0,0 @@
|
||||
package sections
|
||||
|
||||
import models "github.com/onsonr/sonr/internal/orm/marketing"
|
||||
|
||||
templ Highlights(highlights *models.Highlights) {
|
||||
<!-- Features -->
|
||||
<section class="relative bg-zinc-50">
|
||||
<div class="py-12 md:py-20">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6">
|
||||
<div class="max-w-3xl mx-auto text-center pb-12">
|
||||
<h2
|
||||
class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4"
|
||||
>
|
||||
{ highlights.Heading }
|
||||
</h2>
|
||||
<p class="text-lg text-zinc-500">
|
||||
{ highlights.Subtitle }
|
||||
</p>
|
||||
</div>
|
||||
<div x-data="{ tab: '1' }">
|
||||
<!-- Tabs buttons -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6">
|
||||
<button
|
||||
:class="tab !== '1' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
|
||||
class="text-left px-4 py-5 border border-transparent rounded"
|
||||
@click.prevent="tab = '1'"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="font-inter-tight font-semibold text-zinc-900">
|
||||
Experience
|
||||
</div>
|
||||
<svg
|
||||
:class="tab !== '1' ? 'hidden' : ''"
|
||||
class="fill-zinc-400 shrink-0 ml-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="10"
|
||||
height="10"
|
||||
>
|
||||
<path
|
||||
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-sm text-zinc-500">
|
||||
Sonr is completely designed to be frictionless for every kind of user.
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
:class="tab !== '2' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
|
||||
class="text-left px-4 py-5 border border-transparent rounded"
|
||||
@click.prevent="tab = '2'"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="font-inter-tight font-semibold text-zinc-900">
|
||||
Compliance
|
||||
</div>
|
||||
<svg
|
||||
:class="tab !== '2' ? 'hidden' : ''"
|
||||
class="fill-zinc-400 shrink-0 ml-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="10"
|
||||
height="10"
|
||||
>
|
||||
<path
|
||||
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-sm text-zinc-500">
|
||||
Sonr is managed by a USA-based Wyoming DUNA, which is fully compliant with the GDPR.
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
:class="tab !== '3' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
|
||||
class="text-left px-4 py-5 border border-transparent rounded"
|
||||
@click.prevent="tab = '3'"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="font-inter-tight font-semibold text-zinc-900">
|
||||
Interoperability
|
||||
</div>
|
||||
<svg
|
||||
:class="tab !== '3' ? 'hidden' : ''"
|
||||
class="fill-zinc-400 shrink-0 ml-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="10"
|
||||
height="10"
|
||||
>
|
||||
<path
|
||||
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-sm text-zinc-500">
|
||||
Sonr is designed to work cross-platform, cross-network, and cross-chain.
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
:class="tab !== '4' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'"
|
||||
class="text-left px-4 py-5 border border-transparent rounded"
|
||||
@click.prevent="tab = '4'"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="font-inter-tight font-semibold text-zinc-900">
|
||||
Security
|
||||
</div>
|
||||
<svg
|
||||
:class="tab !== '4' ? 'hidden' : ''"
|
||||
class="fill-zinc-400 shrink-0 ml-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="10"
|
||||
height="10"
|
||||
>
|
||||
<path
|
||||
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-sm text-zinc-500">
|
||||
Sonr eliminates 99.9% of attack vectors with its quantum-resistant encryption.
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Tabs items -->
|
||||
<div
|
||||
class="relative lg:max-w-none [mask-image:linear-gradient(white_0%,white_calc(100%-40px),_transparent_calc(100%-1px))] -mx-6"
|
||||
>
|
||||
<div class="relative flex flex-col pt-12 md:pt-20 mx-6">
|
||||
<!-- Item 1 -->
|
||||
<div
|
||||
class="w-full text-center"
|
||||
x-show="tab === '1'"
|
||||
x-transition:enter="transition ease-in-out duration-700 transform order-first"
|
||||
x-transition:enter-start="opacity-0 -translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="transition ease-in-out duration-300 transform absolute"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 translate-y-4"
|
||||
>
|
||||
<div class="inline-flex relative align-top">
|
||||
<img
|
||||
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
|
||||
src="./images/feature-01.png"
|
||||
width="600"
|
||||
height="360"
|
||||
alt="Feature 01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 2 -->
|
||||
<div
|
||||
class="w-full text-center"
|
||||
x-show="tab === '2'"
|
||||
x-transition:enter="transition ease-in-out duration-700 transform order-first"
|
||||
x-transition:enter-start="opacity-0 -translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="transition ease-in-out duration-300 transform absolute"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 translate-y-4"
|
||||
>
|
||||
<div class="inline-flex relative align-top">
|
||||
<img
|
||||
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
|
||||
src="./images/feature-01.png"
|
||||
width="600"
|
||||
height="360"
|
||||
alt="Feature 02"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 3 -->
|
||||
<div
|
||||
class="w-full text-center"
|
||||
x-show="tab === '3'"
|
||||
x-transition:enter="transition ease-in-out duration-700 transform order-first"
|
||||
x-transition:enter-start="opacity-0 -translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="transition ease-in-out duration-300 transform absolute"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 translate-y-4"
|
||||
>
|
||||
<div class="inline-flex relative align-top">
|
||||
<img
|
||||
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
|
||||
src="./images/feature-01.png"
|
||||
width="600"
|
||||
height="360"
|
||||
alt="Feature 03"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 4 -->
|
||||
<div
|
||||
class="w-full text-center"
|
||||
x-show="tab === '4'"
|
||||
x-transition:enter="transition ease-in-out duration-700 transform order-first"
|
||||
x-transition:enter-start="opacity-0 -translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="transition ease-in-out duration-300 transform absolute"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 translate-y-4"
|
||||
>
|
||||
<div class="inline-flex relative align-top">
|
||||
<img
|
||||
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
|
||||
src="./images/feature-01.png"
|
||||
width="600"
|
||||
height="360"
|
||||
alt="Feature 04"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
package home
|
||||
package marketing
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/home/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/marketing/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package home
|
||||
package marketing
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
@ -9,7 +9,7 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/home/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/components/marketing/sections"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
)
|
||||
|
18
pkg/nebula/components/marketing/route.go
Normal file
18
pkg/nebula/components/marketing/route.go
Normal file
@ -0,0 +1,18 @@
|
||||
package marketing
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/onsonr/sonr/internal/ctx"
|
||||
)
|
||||
|
||||
func HomeRoute(c echo.Context) error {
|
||||
s, err := ctx.GetHWAYContext(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("Session ID: %s", s.ID())
|
||||
return ctx.RenderTempl(c, View())
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package sections
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
models "github.com/onsonr/sonr/internal/orm/marketing"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
||||
@ -13,7 +14,7 @@ templ Hero(hero *models.Hero) {
|
||||
<div class="px-4 sm:px-6">
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="text-center pb-12 md:pb-16">
|
||||
<h1 class="font-inter-tight text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4">
|
||||
<h1 class="font-fancy text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4">
|
||||
{ hero.TitleFirst }
|
||||
<em class="italic relative inline-flex justify-center items-center text-zinc-900">
|
||||
{ hero.TitleEmphasis }
|
||||
@ -58,7 +59,7 @@ templ stats(stats []*models.Stat) {
|
||||
<div class="max-w-sm mx-auto grid gap-12 sm:grid-cols-2 md:grid-cols-4 md:-mx-5 md:gap-0 items-end md:max-w-none">
|
||||
for _, item := range stats {
|
||||
<div class="relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden">
|
||||
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data="counter(476)" x-text="counterValue">{ item.Value }</span>{ item.Denom }</h4>
|
||||
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data={ getCounter(item.Value) } x-text="counterValue">{ item.Value }</span>{ item.Denom }</h4>
|
||||
<p class="text-sm text-zinc-500">{ item.Label }</p>
|
||||
</div>
|
||||
}
|
||||
@ -67,6 +68,10 @@ templ stats(stats []*models.Stat) {
|
||||
</div>
|
||||
}
|
||||
|
||||
func getCounter(value string) string {
|
||||
return fmt.Sprintf("counter(%s)", value)
|
||||
}
|
||||
|
||||
script counterAnimation() {
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('counter', (target = 0, duration = 3000) => ({
|
@ -9,6 +9,7 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
models "github.com/onsonr/sonr/internal/orm/marketing"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/ui"
|
||||
)
|
||||
@ -34,14 +35,14 @@ func Hero(hero *models.Hero) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!-- Hero --><section class=\"relative before:absolute before:inset-0 before:h-80 before:pointer-events-none before:bg-gradient-to-b before:from-zinc-100 before:-z-10\"><div class=\"pt-32 pb-12 md:pt-40 md:pb-20\"><!-- Section content --><div class=\"px-4 sm:px-6\"><div class=\"max-w-3xl mx-auto\"><div class=\"text-center pb-12 md:pb-16\"><h1 class=\"font-inter-tight text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!-- Hero --><section class=\"relative before:absolute before:inset-0 before:h-80 before:pointer-events-none before:bg-gradient-to-b before:from-zinc-100 before:-z-10\"><div class=\"pt-32 pb-12 md:pt-40 md:pb-20\"><!-- Section content --><div class=\"px-4 sm:px-6\"><div class=\"max-w-3xl mx-auto\"><div class=\"text-center pb-12 md:pb-16\"><h1 class=\"font-fancy text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleFirst)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 17, Col: 24}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 18, Col: 24}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -54,7 +55,7 @@ func Hero(hero *models.Hero) templ.Component {
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleEmphasis)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 19, Col: 28}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 20, Col: 28}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -67,7 +68,7 @@ func Hero(hero *models.Hero) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(hero.TitleSecond)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 24, Col: 25}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 25, Col: 25}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -80,7 +81,7 @@ func Hero(hero *models.Hero) templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Subtitle)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 27, Col: 22}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 28, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -146,7 +147,7 @@ func heroImage(hero *models.Hero) templ.Component {
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Src)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 47, Col: 23}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 48, Col: 23}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -159,7 +160,7 @@ func heroImage(hero *models.Hero) templ.Component {
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Width)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 48, Col: 27}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 49, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -172,7 +173,7 @@ func heroImage(hero *models.Hero) templ.Component {
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Height)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 49, Col: 29}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 50, Col: 29}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -212,29 +213,42 @@ func stats(stats []*models.Stat) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, item := range stats {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden\"><h4 class=\"font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2\"><span x-data=\"counter(476)\" x-text=\"counterValue\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden\"><h4 class=\"font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2\"><span x-data=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(item.Value)
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(getCounter(item.Value))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 61, Col: 145}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 62, Col: 120}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-text=\"counterValue\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(item.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 62, Col: 157}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(item.Denom)
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(item.Denom)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 61, Col: 166}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 62, Col: 178}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -242,12 +256,12 @@ func stats(stats []*models.Stat) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label)
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/home/sections/hero.templ`, Line: 62, Col: 50}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/hero.templ`, Line: 63, Col: 50}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -272,6 +286,10 @@ func stats(stats []*models.Stat) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func getCounter(value string) string {
|
||||
return fmt.Sprintf("counter(%s)", value)
|
||||
}
|
||||
|
||||
func counterAnimation() templ.ComponentScript {
|
||||
return templ.ComponentScript{
|
||||
Name: `__templ_counterAnimation_cac3`,
|
102
pkg/nebula/components/marketing/sections/highlights.templ
Normal file
102
pkg/nebula/components/marketing/sections/highlights.templ
Normal file
@ -0,0 +1,102 @@
|
||||
package sections
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
models "github.com/onsonr/sonr/internal/orm/marketing"
|
||||
)
|
||||
|
||||
templ Highlights(highlights *models.Highlights) {
|
||||
<!-- Features -->
|
||||
<section class="relative bg-zinc-50">
|
||||
<div class="py-12 md:py-20">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6">
|
||||
<div class="max-w-3xl mx-auto text-center pb-12">
|
||||
<h2
|
||||
class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4"
|
||||
>
|
||||
{ highlights.Heading }
|
||||
</h2>
|
||||
<p class="text-lg text-zinc-500">
|
||||
{ highlights.Subtitle }
|
||||
</p>
|
||||
</div>
|
||||
<div x-data="{ tab: '1' }">
|
||||
<!-- Tabs buttons -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6">
|
||||
@highlightTab(1, highlights.Features[0])
|
||||
@highlightTab(2, highlights.Features[1])
|
||||
@highlightTab(3, highlights.Features[2])
|
||||
@highlightTab(4, highlights.Features[3])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ highlightTab(index int, highlight *models.Feature) {
|
||||
<button
|
||||
:class={ getSelectedClass(index) }
|
||||
class="text-left px-4 py-5 border border-transparent rounded"
|
||||
@click.prevent={ getClickPrevent(index) }
|
||||
>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="font-inter-tight font-semibold text-zinc-900">
|
||||
{ highlight.Title }
|
||||
</div>
|
||||
<svg
|
||||
:class={ getShowBorder(index) }
|
||||
class="fill-zinc-400 shrink-0 ml-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="10"
|
||||
height="10"
|
||||
>
|
||||
<path
|
||||
d="M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="text-sm text-zinc-500">
|
||||
{ highlight.Desc }
|
||||
</div>
|
||||
</button>
|
||||
}
|
||||
|
||||
templ highlightCard(index int, highlight *models.Feature) {
|
||||
<div
|
||||
class="w-full text-center"
|
||||
x-show={ getXShow(index) }
|
||||
x-transition:enter="transition ease-in-out duration-700 transform order-first"
|
||||
x-transition:enter-start="opacity-0 -translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="transition ease-in-out duration-300 transform absolute"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 translate-y-4"
|
||||
>
|
||||
<div class="inline-flex relative align-top">
|
||||
<img
|
||||
class="rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl"
|
||||
src={ highlight.Image.Src }
|
||||
width={ highlight.Image.Width }
|
||||
height={ highlight.Image.Height }
|
||||
alt={ highlight.Title }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
func getSelectedClass(index int) string {
|
||||
return fmt.Sprintf("tab === '%d' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'", index+1)
|
||||
}
|
||||
|
||||
func getShowBorder(index int) string {
|
||||
return fmt.Sprintf("tab === '%d' ? 'hidden' : ''", index+1)
|
||||
}
|
||||
|
||||
func getClickPrevent(index int) string {
|
||||
return fmt.Sprintf("tab = '%d'", index+1)
|
||||
}
|
||||
|
||||
func getXShow(index int) string {
|
||||
return fmt.Sprintf("tab === '%d'", index+1)
|
||||
}
|
287
pkg/nebula/components/marketing/sections/highlights_templ.go
Normal file
287
pkg/nebula/components/marketing/sections/highlights_templ.go
Normal file
@ -0,0 +1,287 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package sections
|
||||
|
||||
//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 (
|
||||
"fmt"
|
||||
models "github.com/onsonr/sonr/internal/orm/marketing"
|
||||
)
|
||||
|
||||
func Highlights(highlights *models.Highlights) 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("<!-- Features --><section class=\"relative bg-zinc-50\"><div class=\"py-12 md:py-20\"><div class=\"max-w-5xl mx-auto px-4 sm:px-6\"><div class=\"max-w-3xl mx-auto text-center pb-12\"><h2 class=\"font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Heading)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 17, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2><p class=\"text-lg text-zinc-500\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Subtitle)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 20, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div><div x-data=\"{ tab: '1' }\"><!-- Tabs buttons --><div class=\"grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = highlightTab(1, highlights.Features[0]).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = highlightTab(2, highlights.Features[1]).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div></div></section>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func highlightTab(index int, highlight *models.Feature) 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_Err = templ_7745c5c3_Buffer.WriteString("<button :class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(getSelectedClass(index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 37, Col: 34}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"text-left px-4 py-5 border border-transparent rounded\" @click.prevent=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(getClickPrevent(index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 39, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><div class=\"flex items-center justify-between mb-1\"><div class=\"font-inter-tight font-semibold text-zinc-900\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 43, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><svg :class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(getShowBorder(index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 46, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"fill-zinc-400 shrink-0 ml-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\"><path d=\"M8.667.186H2.675a.999.999 0 0 0 0 1.998h3.581L.971 7.469a.999.999 0 1 0 1.412 1.412l5.285-5.285v3.58a.999.999 0 1 0 1.998 0V1.186a.999.999 0 0 0-.999-.999Z\"></path></svg></div><div class=\"text-sm text-zinc-500\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Desc)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 58, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func highlightCard(index int, highlight *models.Feature) 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_Var10 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var10 == nil {
|
||||
templ_7745c5c3_Var10 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"w-full text-center\" x-show=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(getXShow(index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 66, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-transition:enter=\"transition ease-in-out duration-700 transform order-first\" x-transition:enter-start=\"opacity-0 -translate-y-4\" x-transition:enter-end=\"opacity-100 translate-y-0\" x-transition:leave=\"transition ease-in-out duration-300 transform absolute\" x-transition:leave-start=\"opacity-100 translate-y-0\" x-transition:leave-end=\"opacity-0 translate-y-4\"><div class=\"inline-flex relative align-top\"><img class=\"rounded-t-lg border border-transparent [background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] box-content shadow-2xl\" src=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Src)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 77, Col: 29}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" width=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Width)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 78, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" height=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Height)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 79, Col: 35}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" alt=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/nebula/components/marketing/sections/highlights.templ`, Line: 80, Col: 25}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func getSelectedClass(index int) string {
|
||||
return fmt.Sprintf("tab === '%d' ? 'bg-zinc-100 opacity-60 hover:opacity-100 transition' : '[background:linear-gradient(theme(colors.white),theme(colors.white))_padding-box,linear-gradient(120deg,theme(colors.zinc.300),theme(colors.zinc.100),theme(colors.zinc.300))_border-box] shadow-sm rotate-1'", index+1)
|
||||
}
|
||||
|
||||
func getShowBorder(index int) string {
|
||||
return fmt.Sprintf("tab === '%d' ? 'hidden' : ''", index+1)
|
||||
}
|
||||
|
||||
func getClickPrevent(index int) string {
|
||||
return fmt.Sprintf("tab = '%d'", index+1)
|
||||
}
|
||||
|
||||
func getXShow(index int) string {
|
||||
return fmt.Sprintf("tab === '%d'", index+1)
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -1,4 +1,4 @@
|
||||
package home
|
||||
package marketing
|
||||
|
||||
import models "github.com/onsonr/sonr/internal/orm/marketing"
|
||||
|
||||
@ -27,22 +27,22 @@ var highlights = &models.Highlights{
|
||||
Subtitle: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.",
|
||||
Features: []*models.Feature{
|
||||
{
|
||||
Title: "Infinite-Factor Authentication",
|
||||
Title: "∞-Factor Auth",
|
||||
Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.",
|
||||
Icon: nil,
|
||||
},
|
||||
{
|
||||
Title: "Self-Custody BTC & ETH",
|
||||
Title: "Data Ownership",
|
||||
Desc: "Sonr leverages advanced cryptography to permit facilitating Wallet Operations directly on-chain, without the need for a centralized server.",
|
||||
Icon: nil,
|
||||
},
|
||||
{
|
||||
Title: "mAiNsTrEaM Ready",
|
||||
Title: "Everyday Transactions",
|
||||
Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.",
|
||||
Icon: nil,
|
||||
},
|
||||
{
|
||||
Title: "DAO Governed",
|
||||
Title: "Limitless Possibilities",
|
||||
Desc: "Sonr is a proudly American Project which operates under the new Wyoming DUNA Legal Framework, ensuring the protection of your digital rights.",
|
||||
Icon: nil,
|
||||
},
|
||||
@ -54,25 +54,18 @@ var mission = &models.Mission{
|
||||
Heading: "The Protocol for Decentralized Identity & Authentication",
|
||||
Subtitle: "We're creating the Global Standard for Decentralized Identity. Authenticate users with PassKeys, Issue Crypto Wallets, Build Payment flows, Send Encrypted Messages - all on a single platform.",
|
||||
Experience: &models.Feature{
|
||||
Title: "Experience",
|
||||
Title: "Less is More",
|
||||
Desc: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.",
|
||||
Icon: nil,
|
||||
},
|
||||
Compliance: &models.Feature{
|
||||
Title: "Compliance",
|
||||
Title: "Works where there's Internet",
|
||||
Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.",
|
||||
Icon: nil,
|
||||
},
|
||||
Interoperability: &models.Feature{
|
||||
Title: "Interoperability",
|
||||
Title: "American Made DUNA",
|
||||
Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.",
|
||||
Icon: nil,
|
||||
},
|
||||
Standards: []*models.Feature{
|
||||
{
|
||||
Title: "Standards",
|
||||
Desc: "Sonr is a proudly American Project which operates under the new Wyoming DUNA Legal Framework, ensuring the protection of your digital rights.",
|
||||
Icon: nil,
|
||||
},
|
||||
},
|
||||
}
|
@ -1,21 +1,16 @@
|
||||
package index
|
||||
package vaultindex
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ipfs/boxo/files"
|
||||
"github.com/onsonr/sonr/internal/dwn/gen"
|
||||
)
|
||||
|
||||
func BuildFile(cnfg *gen.Config) (files.Node, error) {
|
||||
_, err := json.Marshal(cnfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w := bytes.NewBuffer(nil)
|
||||
err = IndexFile().Render(context.Background(), w)
|
||||
err := IndexFile().Render(context.Background(), w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
@ -1,31 +1,29 @@
|
||||
package index
|
||||
package vaultindex
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/internal/dwn/gen"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/state"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
)
|
||||
|
||||
func ConfigFile(dwnConfig *gen.Config) {
|
||||
}
|
||||
|
||||
templ IndexFile() {
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@styles.Styles()
|
||||
@styles.Alpine()
|
||||
@styles.Htmx()
|
||||
@styles.Styles()
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Sonr DWN</title>
|
||||
@state.RegisterServiceWorker()
|
||||
</head>
|
||||
<body class="flex items-center justify-center h-full bg-neutral-50 lg:p-24 md:16 p-4">
|
||||
@styles.Toaster() {
|
||||
<body class="flex items-center justify-center h-full bg-zinc-50 lg:p-24 md:16 p-4">
|
||||
<main class="flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3">
|
||||
<div id="output">Loading...</div>
|
||||
<div hx-get="/#" swap="outerHTML">Loading...</div>
|
||||
</main>
|
||||
</body>
|
||||
}
|
||||
</html>
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package index
|
||||
package vaultindex
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
@ -9,14 +9,10 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/internal/dwn/gen"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/state"
|
||||
"github.com/onsonr/sonr/pkg/nebula/global/styles"
|
||||
)
|
||||
|
||||
func ConfigFile(dwnConfig *gen.Config) {
|
||||
}
|
||||
|
||||
func IndexFile() 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
|
||||
@ -42,6 +38,10 @@ func IndexFile() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = styles.Styles().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = styles.Alpine().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@ -50,10 +50,6 @@ func IndexFile() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = styles.Styles().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Sonr DWN</title>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@ -62,7 +58,33 @@ func IndexFile() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</head><body class=\"flex items-center justify-center h-full bg-neutral-50 lg:p-24 md:16 p-4\"><main class=\"flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3\"><div id=\"output\">Loading...</div></main></body></html>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</head>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
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("<body class=\"flex items-center justify-center h-full bg-zinc-50 lg:p-24 md:16 p-4\"><main class=\"flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3\"><div hx-get=\"/#\" swap=\"outerHTML\">Loading...</div></main></body>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = styles.Toaster().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</html>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
@ -34,11 +34,36 @@ async function main() {
|
||||
"./assets/js/alpine.min.js",
|
||||
);
|
||||
|
||||
// Fetch alpin-focus.min.js
|
||||
await fetchAndSave(
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/alpinejs-focus/3.14.1/cdn.min.js",
|
||||
"./assets/js/alpin-focus.min.js",
|
||||
);
|
||||
|
||||
// Fetch dexie.min.js
|
||||
await fetchAndSave(
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/dexie/4.0.8/dexie.min.js",
|
||||
"./assets/js/dexie.min.js",
|
||||
);
|
||||
|
||||
// Fetch d3.min.js
|
||||
await fetchAndSave(
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js",
|
||||
"./assets/js/d3.min.js",
|
||||
);
|
||||
|
||||
// TopoJSON
|
||||
await fetchAndSave(
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js",
|
||||
"./assets/js/topojson.min.js",
|
||||
);
|
||||
|
||||
// Datamaps
|
||||
await fetchAndSave(
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/datamaps/0.5.9/datamaps.world.min.js",
|
||||
"./assets/js/datamaps.world.min.js",
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
main();
|
||||
|
@ -1,92 +0,0 @@
|
||||
package state
|
||||
|
||||
templ NavigatorCredentialsCreate() {
|
||||
<script>
|
||||
function createCredential() {
|
||||
navigator.credentials.create({
|
||||
publicKey: {
|
||||
rp: {
|
||||
name: "Sonr",
|
||||
},
|
||||
user: {
|
||||
id: new Uint8Array(0),
|
||||
name: "Sonr",
|
||||
displayName: "Sonr",
|
||||
},
|
||||
challenge: new Uint8Array(0),
|
||||
pubKeyCredParams: [{
|
||||
type: "public-key",
|
||||
alg: -7,
|
||||
}],
|
||||
timeout: 60000,
|
||||
excludeCredentials: [],
|
||||
authenticatorSelection: {
|
||||
requireResidentKey: false,
|
||||
userVerification: "discouraged",
|
||||
},
|
||||
},
|
||||
})
|
||||
.then((assertion) => {
|
||||
console.log("Assertion:", assertion);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
|
||||
templ NavigatorCredentialsGet() {
|
||||
<script>
|
||||
function getCredential() {
|
||||
navigator.credentials.get({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array(0),
|
||||
allowCredentials: [],
|
||||
timeout: 60000,
|
||||
userVerification: "discouraged",
|
||||
},
|
||||
})
|
||||
.then((assertion) => {
|
||||
console.log("Assertion:", assertion);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
|
||||
templ NavigatorCredentialsGetAll() {
|
||||
<script>
|
||||
navigator.credentials.getAll({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array(0),
|
||||
allowCredentials: [],
|
||||
timeout: 60000,
|
||||
userVerification: "discouraged",
|
||||
extensions: {
|
||||
|
||||
}
|
||||
},
|
||||
})
|
||||
.then((assertion) => {
|
||||
console.log("Assertion:", assertion);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
</script>
|
||||
}
|
||||
|
||||
templ NavigatorCredentialsHasPasskey() {
|
||||
<script>
|
||||
navigator.credentials.has()
|
||||
.then((has) => {
|
||||
console.log("Has Passkey:", has);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error:", error);
|
||||
});
|
||||
</script>
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package state
|
||||
|
||||
//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 NavigatorCredentialsCreate() 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("<script>\n\tfunction createCredential() {\n\t\tnavigator.credentials.create({\n\t\t\tpublicKey: {\n\t\t\t\trp: {\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tuser: {\n\t\t\t\t\tid: new Uint8Array(0),\n\t\t\t\t\tname: \"Sonr\",\n\t\t\t\t\tdisplayName: \"Sonr\",\n\t\t\t\t},\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tpubKeyCredParams: [{\n\t\t\t\t\ttype: \"public-key\",\n\t\t\t\t\talg: -7,\n\t\t\t\t}],\n\t\t\t\ttimeout: 60000,\n\t\t\t\texcludeCredentials: [],\n\t\t\t\tauthenticatorSelection: {\n\t\t\t\t\trequireResidentKey: false,\n\t\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t\t}\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func NavigatorCredentialsGet() 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_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tfunction getCredential() {\n\t\tnavigator.credentials.get({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tallowCredentials: [],\n\t\t\t\ttimeout: 60000,\n\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t}\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func NavigatorCredentialsGetAll() 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 = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tnavigator.credentials.getAll({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge: new Uint8Array(0),\n\t\t\t\tallowCredentials: [],\n\t\t\t\ttimeout: 60000,\n\t\t\t\tuserVerification: \"discouraged\",\n\t\t\t\textensions: {\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t},\n\t\t})\n\t\t\t.then((assertion) => {\n\t\t\t\tconsole.log(\"Assertion:\", assertion);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func NavigatorCredentialsHasPasskey() 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_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tnavigator.credentials.has()\n\t\t\t.then((has) => {\n\t\t\t\tconsole.log(\"Has Passkey:\", has);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error(\"Error:\", error);\n\t\t\t});\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -15,3 +15,14 @@ templ InsertAccount(accountName string) {
|
||||
console.log("Inserted account with ID:", accountId);
|
||||
</script>
|
||||
}
|
||||
|
||||
templ InsertCredential(credentialName string) {
|
||||
<script>
|
||||
const credentialId = await motr.insertCredential({
|
||||
name: credentialName,
|
||||
createdAt: new Date(),
|
||||
});
|
||||
|
||||
console.log("Inserted credential with ID:", credentialId);
|
||||
</script>
|
||||
}
|
||||
|
@ -37,4 +37,33 @@ func InsertAccount(accountName string) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func InsertCredential(credentialName string) 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_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tconst credentialId = await motr.insertCredential({\n\t\t\tname: credentialName,\n\t\t\tcreatedAt: new Date(),\n\t\t});\n\n\t\tconsole.log(\"Inserted credential with ID:\", credentialId);\n\t</script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
|
@ -1 +0,0 @@
|
||||
package state
|
@ -1,13 +1,15 @@
|
||||
package state
|
||||
|
||||
var (
|
||||
serviceWorkerHandle = templ.NewOnceHandle()
|
||||
serviceWorkerInstall = templ.NewOnceHandle()
|
||||
serviceWorkerReady = templ.NewOnceHandle()
|
||||
)
|
||||
|
||||
templ RegisterServiceWorker() {
|
||||
@serviceWorkerHandle.Once() {
|
||||
<script>
|
||||
@serviceWorkerInstall.Once() {
|
||||
<script type="text/javascript">
|
||||
if ("serviceWorker" in navigator) {
|
||||
// Register the service worker
|
||||
window.addEventListener("load", function() {
|
||||
navigator.serviceWorker
|
||||
.register("/sw.js")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user