mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
refactor: move gateway and vault packages to internal directory
This commit is contained in:
@@ -1,111 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.hway.Env`. DO NOT EDIT.
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/apple/pkl-go/pkl"
|
||||
)
|
||||
|
||||
type Env interface {
|
||||
GetServePort() int
|
||||
|
||||
GetConfigDir() string
|
||||
|
||||
GetSqliteFile() string
|
||||
|
||||
GetChainId() string
|
||||
|
||||
GetIpfsGatewayUrl() string
|
||||
|
||||
GetSonrApiUrl() string
|
||||
|
||||
GetSonrGrpcUrl() string
|
||||
|
||||
GetSonrRpcUrl() string
|
||||
|
||||
GetTurnstileSiteKey() string
|
||||
}
|
||||
|
||||
var _ Env = (*EnvImpl)(nil)
|
||||
|
||||
type EnvImpl struct {
|
||||
ServePort int `pkl:"servePort"`
|
||||
|
||||
ConfigDir string `pkl:"configDir"`
|
||||
|
||||
SqliteFile string `pkl:"sqliteFile"`
|
||||
|
||||
ChainId string `pkl:"chainId"`
|
||||
|
||||
IpfsGatewayUrl string `pkl:"ipfsGatewayUrl"`
|
||||
|
||||
SonrApiUrl string `pkl:"sonrApiUrl"`
|
||||
|
||||
SonrGrpcUrl string `pkl:"sonrGrpcUrl"`
|
||||
|
||||
SonrRpcUrl string `pkl:"sonrRpcUrl"`
|
||||
|
||||
TurnstileSiteKey string `pkl:"turnstileSiteKey"`
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetServePort() int {
|
||||
return rcv.ServePort
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetConfigDir() string {
|
||||
return rcv.ConfigDir
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetSqliteFile() string {
|
||||
return rcv.SqliteFile
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetChainId() string {
|
||||
return rcv.ChainId
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetIpfsGatewayUrl() string {
|
||||
return rcv.IpfsGatewayUrl
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetSonrApiUrl() string {
|
||||
return rcv.SonrApiUrl
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetSonrGrpcUrl() string {
|
||||
return rcv.SonrGrpcUrl
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetSonrRpcUrl() string {
|
||||
return rcv.SonrRpcUrl
|
||||
}
|
||||
|
||||
func (rcv *EnvImpl) GetTurnstileSiteKey() string {
|
||||
return rcv.TurnstileSiteKey
|
||||
}
|
||||
|
||||
// LoadFromPath loads the pkl module at the given path and evaluates it into a Env
|
||||
func LoadFromPath(ctx context.Context, path string) (ret Env, err error) {
|
||||
evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
cerr := evaluator.Close()
|
||||
if err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}()
|
||||
ret, err = Load(ctx, evaluator, pkl.FileSource(path))
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Load loads the pkl module at the given source and evaluates it with the given evaluator into a Env
|
||||
func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (Env, error) {
|
||||
var ret EnvImpl
|
||||
if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ret, nil
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/apple/pkl-go/pkl"
|
||||
)
|
||||
|
||||
// LoadFromBytes loads the environment from the given bytes
|
||||
func LoadFromBytes(data []byte) (Env, error) {
|
||||
text := string(data)
|
||||
return LoadFromString(text)
|
||||
}
|
||||
|
||||
// LoadFromString loads the environment from the given string
|
||||
func LoadFromString(text string) (Env, error) {
|
||||
evaluator, err := pkl.NewEvaluator(context.Background(), pkl.PreconfiguredOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
cerr := evaluator.Close()
|
||||
if err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}()
|
||||
ret, err := Load(context.Background(), evaluator, pkl.TextSource(text))
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// LoadFromURL loads the environment from the given URL
|
||||
func LoadFromURL(url string) (Env, error) {
|
||||
evaluator, err := pkl.NewEvaluator(context.Background(), pkl.PreconfiguredOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
cerr := evaluator.Close()
|
||||
if err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}()
|
||||
ret, err := Load(context.Background(), evaluator, pkl.UriSource(url))
|
||||
return ret, err
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.hway.Env`. DO NOT EDIT.
|
||||
package config
|
||||
|
||||
import "github.com/apple/pkl-go/pkl"
|
||||
|
||||
func init() {
|
||||
pkl.RegisterMapping("sonr.hway.Env", EnvImpl{})
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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>
|
||||
|
||||
<!-- HTMX -->
|
||||
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
||||
|
||||
<!-- WASM Support -->
|
||||
<script src="https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js"></script>
|
||||
|
||||
<!-- Main JS -->
|
||||
<script src="main.js"></script>
|
||||
|
||||
<!-- Tailwind (assuming you're using it based on your classes) -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
|
||||
<!-- Add manifest for PWA support -->
|
||||
<link
|
||||
rel="manifest"
|
||||
href="/app.webmanifest"
|
||||
crossorigin="use-credentials"
|
||||
/>
|
||||
|
||||
<!-- Offline detection styles -->
|
||||
<style>
|
||||
.offline-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.offline .offline-indicator {
|
||||
display: block;
|
||||
background: #f44336;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 0.5rem;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body
|
||||
class="flex items-center justify-center h-full bg-zinc-50 lg:p-24 md:16 p-4"
|
||||
>
|
||||
<!-- Offline indicator -->
|
||||
<div class="offline-indicator">
|
||||
You are currently offline. Some features may be limited.
|
||||
</div>
|
||||
|
||||
<!-- Loading indicator -->
|
||||
<div
|
||||
id="loading-indicator"
|
||||
class="fixed top-0 left-0 w-full h-1 bg-blue-200 transition-all duration-300"
|
||||
style="display: none"
|
||||
>
|
||||
<div class="h-full bg-blue-600 w-0 transition-all duration-300"></div>
|
||||
</div>
|
||||
|
||||
<main
|
||||
class="flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3"
|
||||
>
|
||||
<div
|
||||
id="content"
|
||||
hx-get="/#"
|
||||
hx-trigger="load"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="#loading-indicator"
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- WASM Ready Indicator (hidden) -->
|
||||
<div
|
||||
id="wasm-status"
|
||||
class="hidden fixed bottom-4 right-4 p-2 rounded-md bg-green-500 text-white"
|
||||
hx-swap-oob="true"
|
||||
>
|
||||
WASM Ready
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Initialize service worker
|
||||
if ("serviceWorker" in navigator) {
|
||||
window.addEventListener("load", async function () {
|
||||
try {
|
||||
const registration =
|
||||
await navigator.serviceWorker.register("/sw.js");
|
||||
console.log(
|
||||
"Service Worker registered with scope:",
|
||||
registration.scope,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Service Worker registration failed:", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// HTMX loading indicator
|
||||
htmx.on("htmx:beforeRequest", function (evt) {
|
||||
document.getElementById("loading-indicator").style.display = "block";
|
||||
});
|
||||
|
||||
htmx.on("htmx:afterRequest", function (evt) {
|
||||
document.getElementById("loading-indicator").style.display = "none";
|
||||
});
|
||||
|
||||
// WASM ready event handler
|
||||
document.addEventListener("wasm-ready", function () {
|
||||
const status = document.getElementById("wasm-status");
|
||||
status.classList.remove("hidden");
|
||||
setTimeout(() => {
|
||||
status.classList.add("hidden");
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
// Offline status handler
|
||||
window.addEventListener("offline", function () {
|
||||
document.body.classList.add("offline");
|
||||
});
|
||||
|
||||
window.addEventListener("online", function () {
|
||||
document.body.classList.remove("offline");
|
||||
});
|
||||
|
||||
// Initial offline check
|
||||
if (!navigator.onLine) {
|
||||
document.body.classList.add("offline");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,152 +0,0 @@
|
||||
// MessageChannel for WASM communication
|
||||
let wasmChannel;
|
||||
let wasmPort;
|
||||
|
||||
async function initWasmChannel() {
|
||||
wasmChannel = new MessageChannel();
|
||||
wasmPort = wasmChannel.port1;
|
||||
|
||||
// Setup message handling from WASM
|
||||
wasmPort.onmessage = (event) => {
|
||||
const { type, data } = event.data;
|
||||
switch (type) {
|
||||
case 'WASM_READY':
|
||||
console.log('WASM is ready');
|
||||
document.dispatchEvent(new CustomEvent('wasm-ready'));
|
||||
break;
|
||||
case 'RESPONSE':
|
||||
handleWasmResponse(data);
|
||||
break;
|
||||
case 'SYNC_COMPLETE':
|
||||
handleSyncComplete(data);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Initialize WebAssembly and Service Worker
|
||||
async function init() {
|
||||
try {
|
||||
// Register service worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
const registration = await navigator.serviceWorker.register('./sw.js');
|
||||
console.log('ServiceWorker registered');
|
||||
|
||||
// Wait for the service worker to be ready
|
||||
await navigator.serviceWorker.ready;
|
||||
|
||||
// Initialize MessageChannel
|
||||
await initWasmChannel();
|
||||
|
||||
// Send the MessageChannel port to the service worker
|
||||
navigator.serviceWorker.controller.postMessage({
|
||||
type: 'PORT_INITIALIZATION',
|
||||
port: wasmChannel.port2
|
||||
}, [wasmChannel.port2]);
|
||||
|
||||
// Register for periodic sync if available
|
||||
if ('periodicSync' in registration) {
|
||||
try {
|
||||
await registration.periodicSync.register('wasm-sync', {
|
||||
minInterval: 24 * 60 * 60 * 1000 // 24 hours
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('Periodic sync could not be registered:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize HTMX with custom config
|
||||
htmx.config.withCredentials = true;
|
||||
htmx.config.wsReconnectDelay = 'full-jitter';
|
||||
|
||||
// Override HTMX's internal request handling
|
||||
htmx.config.beforeRequest = function (config) {
|
||||
// Add request ID for tracking
|
||||
const requestId = 'req_' + Date.now();
|
||||
config.headers['X-Wasm-Request-ID'] = requestId;
|
||||
|
||||
// If offline, handle through service worker
|
||||
if (!navigator.onLine) {
|
||||
return false; // Let service worker handle it
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Handle HTMX after request
|
||||
htmx.config.afterRequest = function (config) {
|
||||
// Additional processing after request if needed
|
||||
};
|
||||
|
||||
// Handle HTMX errors
|
||||
htmx.config.errorHandler = function (error) {
|
||||
console.error('HTMX Error:', error);
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error('Initialization failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function handleWasmResponse(data) {
|
||||
const { requestId, response } = data;
|
||||
// Process the WASM response
|
||||
// This might update the UI or trigger HTMX swaps
|
||||
const targetElement = document.querySelector(`[data-request-id="${requestId}"]`);
|
||||
if (targetElement) {
|
||||
htmx.process(targetElement);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSyncComplete(data) {
|
||||
const { url } = data;
|
||||
// Handle successful sync
|
||||
// Maybe refresh the relevant part of the UI
|
||||
htmx.trigger('body', 'sync:complete', { url });
|
||||
}
|
||||
|
||||
// Handle offline status changes
|
||||
window.addEventListener('online', () => {
|
||||
document.body.classList.remove('offline');
|
||||
// Trigger sync when back online
|
||||
if (wasmPort) {
|
||||
wasmPort.postMessage({ type: 'SYNC_REQUEST' });
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
document.body.classList.add('offline');
|
||||
});
|
||||
|
||||
// Custom event handlers for HTMX
|
||||
document.addEventListener('htmx:beforeRequest', (event) => {
|
||||
const { elt, xhr } = event.detail;
|
||||
// Add request tracking
|
||||
const requestId = xhr.headers['X-Wasm-Request-ID'];
|
||||
elt.setAttribute('data-request-id', requestId);
|
||||
});
|
||||
|
||||
document.addEventListener('htmx:afterRequest', (event) => {
|
||||
const { elt, successful } = event.detail;
|
||||
if (successful) {
|
||||
elt.removeAttribute('data-request-id');
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize everything when the page loads
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
|
||||
// Export functions that might be needed by WASM
|
||||
window.wasmBridge = {
|
||||
triggerUIUpdate: function (selector, content) {
|
||||
const target = document.querySelector(selector);
|
||||
if (target) {
|
||||
htmx.process(htmx.parse(content).forEach(node => target.appendChild(node)));
|
||||
}
|
||||
},
|
||||
|
||||
showNotification: function (message, type = 'info') {
|
||||
// Implement notification system
|
||||
console.log(`${type}: ${message}`);
|
||||
}
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed index.html
|
||||
var IndexHTML []byte
|
||||
|
||||
//go:embed main.js
|
||||
var MainJS []byte
|
||||
|
||||
//go:embed sw.js
|
||||
var WorkerJS []byte
|
||||
@@ -1,258 +0,0 @@
|
||||
// Cache names for different types of resources
|
||||
const CACHE_NAMES = {
|
||||
wasm: 'wasm-cache-v1',
|
||||
static: 'static-cache-v1',
|
||||
dynamic: 'dynamic-cache-v1'
|
||||
};
|
||||
|
||||
// Import required scripts
|
||||
importScripts(
|
||||
"https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js",
|
||||
"https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v1.1.0/sw.js",
|
||||
);
|
||||
|
||||
// Initialize WASM HTTP listener
|
||||
const wasmInstance = registerWasmHTTPListener("https://cdn.sonr.id/wasm/app.wasm");
|
||||
|
||||
// MessageChannel port for WASM communication
|
||||
let wasmPort;
|
||||
|
||||
// Request queue for offline operations
|
||||
let requestQueue = new Map();
|
||||
|
||||
// Setup message channel handler
|
||||
self.addEventListener('message', async (event) => {
|
||||
if (event.data.type === 'PORT_INITIALIZATION') {
|
||||
wasmPort = event.data.port;
|
||||
setupWasmCommunication();
|
||||
}
|
||||
});
|
||||
|
||||
function setupWasmCommunication() {
|
||||
wasmPort.onmessage = async (event) => {
|
||||
const { type, data } = event.data;
|
||||
|
||||
switch (type) {
|
||||
case 'WASM_REQUEST':
|
||||
handleWasmRequest(data);
|
||||
break;
|
||||
case 'SYNC_REQUEST':
|
||||
processSyncQueue();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Notify that WASM is ready
|
||||
wasmPort.postMessage({ type: 'WASM_READY' });
|
||||
}
|
||||
|
||||
// Enhanced install event
|
||||
self.addEventListener("install", (event) => {
|
||||
event.waitUntil(
|
||||
Promise.all([
|
||||
skipWaiting(),
|
||||
// Cache WASM binary and essential resources
|
||||
caches.open(CACHE_NAMES.wasm).then(cache =>
|
||||
cache.addAll([
|
||||
'https://cdn.sonr.id/wasm/app.wasm',
|
||||
'https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js'
|
||||
])
|
||||
)
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
// Enhanced activate event
|
||||
self.addEventListener("activate", (event) => {
|
||||
event.waitUntil(
|
||||
Promise.all([
|
||||
clients.claim(),
|
||||
// Clean up old caches
|
||||
caches.keys().then(keys =>
|
||||
Promise.all(
|
||||
keys.map(key => {
|
||||
if (!Object.values(CACHE_NAMES).includes(key)) {
|
||||
return caches.delete(key);
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
// Intercept fetch events
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const request = event.request;
|
||||
|
||||
// Handle API requests differently from static resources
|
||||
if (request.url.includes('/api/')) {
|
||||
event.respondWith(handleApiRequest(request));
|
||||
} else {
|
||||
event.respondWith(handleStaticRequest(request));
|
||||
}
|
||||
});
|
||||
|
||||
async function handleApiRequest(request) {
|
||||
try {
|
||||
// Try to make the request
|
||||
const response = await fetch(request.clone());
|
||||
|
||||
// If successful, pass through WASM handler
|
||||
if (response.ok) {
|
||||
return await processWasmResponse(request, response);
|
||||
}
|
||||
|
||||
// If offline or failed, queue the request
|
||||
await queueRequest(request);
|
||||
|
||||
// Return cached response if available
|
||||
const cachedResponse = await caches.match(request);
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
// Return offline response
|
||||
return new Response(
|
||||
JSON.stringify({ error: 'Currently offline' }),
|
||||
{
|
||||
status: 503,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
await queueRequest(request);
|
||||
return new Response(
|
||||
JSON.stringify({ error: 'Request failed' }),
|
||||
{
|
||||
status: 500,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStaticRequest(request) {
|
||||
// Check cache first
|
||||
const cachedResponse = await caches.match(request);
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(request);
|
||||
|
||||
// Cache successful responses
|
||||
if (response.ok) {
|
||||
const cache = await caches.open(CACHE_NAMES.static);
|
||||
cache.put(request, response.clone());
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
// Return offline page for navigation requests
|
||||
if (request.mode === 'navigate') {
|
||||
return caches.match('/offline.html');
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function processWasmResponse(request, response) {
|
||||
// Clone the response before processing
|
||||
const responseClone = response.clone();
|
||||
|
||||
try {
|
||||
// Process through WASM
|
||||
const processedResponse = await wasmInstance.processResponse(responseClone);
|
||||
|
||||
// Notify client through message channel
|
||||
if (wasmPort) {
|
||||
wasmPort.postMessage({
|
||||
type: 'RESPONSE',
|
||||
requestId: request.headers.get('X-Wasm-Request-ID'),
|
||||
response: processedResponse
|
||||
});
|
||||
}
|
||||
|
||||
return processedResponse;
|
||||
} catch (error) {
|
||||
console.error('WASM processing error:', error);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
async function queueRequest(request) {
|
||||
const serializedRequest = await serializeRequest(request);
|
||||
requestQueue.set(request.url, serializedRequest);
|
||||
|
||||
// Register for background sync
|
||||
try {
|
||||
await self.registration.sync.register('wasm-sync');
|
||||
} catch (error) {
|
||||
console.error('Sync registration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function serializeRequest(request) {
|
||||
const headers = {};
|
||||
for (const [key, value] of request.headers.entries()) {
|
||||
headers[key] = value;
|
||||
}
|
||||
|
||||
return {
|
||||
url: request.url,
|
||||
method: request.method,
|
||||
headers,
|
||||
body: await request.text(),
|
||||
timestamp: Date.now()
|
||||
};
|
||||
}
|
||||
|
||||
// Handle background sync
|
||||
self.addEventListener('sync', (event) => {
|
||||
if (event.tag === 'wasm-sync') {
|
||||
event.waitUntil(processSyncQueue());
|
||||
}
|
||||
});
|
||||
|
||||
async function processSyncQueue() {
|
||||
const requests = Array.from(requestQueue.values());
|
||||
|
||||
for (const serializedRequest of requests) {
|
||||
try {
|
||||
const response = await fetch(new Request(serializedRequest.url, {
|
||||
method: serializedRequest.method,
|
||||
headers: serializedRequest.headers,
|
||||
body: serializedRequest.body
|
||||
}));
|
||||
|
||||
if (response.ok) {
|
||||
requestQueue.delete(serializedRequest.url);
|
||||
|
||||
// Notify client of successful sync
|
||||
if (wasmPort) {
|
||||
wasmPort.postMessage({
|
||||
type: 'SYNC_COMPLETE',
|
||||
url: serializedRequest.url
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Sync failed for request:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle payment requests
|
||||
self.addEventListener("canmakepayment", function (e) {
|
||||
e.respondWith(Promise.resolve(true));
|
||||
});
|
||||
|
||||
// Handle periodic sync if available
|
||||
self.addEventListener('periodicsync', (event) => {
|
||||
if (event.tag === 'wasm-sync') {
|
||||
event.waitUntil(processSyncQueue());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
package config
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func newWebManifestBytes() ([]byte, error) {
|
||||
return json.Marshal(baseWebManifest)
|
||||
}
|
||||
|
||||
var baseWebManifest = WebManifest{
|
||||
Name: "Sonr Vault",
|
||||
ShortName: "Sonr.ID",
|
||||
StartURL: "/index.html",
|
||||
Display: "standalone",
|
||||
DisplayOverride: []string{
|
||||
"fullscreen",
|
||||
"minimal-ui",
|
||||
},
|
||||
Icons: []IconDefinition{
|
||||
{
|
||||
Src: "/icons/icon-192x192.png",
|
||||
Sizes: "192x192",
|
||||
Type: "image/png",
|
||||
},
|
||||
},
|
||||
ServiceWorker: ServiceWorker{
|
||||
Scope: "/",
|
||||
Src: "/sw.js",
|
||||
UseCache: true,
|
||||
},
|
||||
ProtocolHandlers: []ProtocolHandler{
|
||||
{
|
||||
Scheme: "did.sonr",
|
||||
URL: "/resolve/sonr/%s",
|
||||
},
|
||||
{
|
||||
Scheme: "did.eth",
|
||||
URL: "/resolve/eth/%s",
|
||||
},
|
||||
{
|
||||
Scheme: "did.btc",
|
||||
URL: "/resolve/btc/%s",
|
||||
},
|
||||
{
|
||||
Scheme: "did.usdc",
|
||||
URL: "/resolve/usdc/%s",
|
||||
},
|
||||
{
|
||||
Scheme: "did.ipfs",
|
||||
URL: "/resolve/ipfs/%s",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type WebManifest struct {
|
||||
// Required fields
|
||||
Name string `json:"name"` // Full name of the application
|
||||
ShortName string `json:"short_name"` // Short version of the name
|
||||
|
||||
// Display and appearance
|
||||
Description string `json:"description,omitempty"` // Purpose and features of the application
|
||||
Display string `json:"display,omitempty"` // Preferred display mode: fullscreen, standalone, minimal-ui, browser
|
||||
DisplayOverride []string `json:"display_override,omitempty"`
|
||||
ThemeColor string `json:"theme_color,omitempty"` // Default theme color for the application
|
||||
BackgroundColor string `json:"background_color,omitempty"` // Background color during launch
|
||||
Orientation string `json:"orientation,omitempty"` // Default orientation: any, natural, landscape, portrait
|
||||
|
||||
// URLs and scope
|
||||
StartURL string `json:"start_url"` // Starting URL when launching
|
||||
Scope string `json:"scope,omitempty"` // Navigation scope of the web application
|
||||
ServiceWorker ServiceWorker `json:"service_worker,omitempty"`
|
||||
|
||||
// Icons
|
||||
Icons []IconDefinition `json:"icons,omitempty"`
|
||||
|
||||
// Optional features
|
||||
RelatedApplications []RelatedApplication `json:"related_applications,omitempty"`
|
||||
PreferRelatedApplications bool `json:"prefer_related_applications,omitempty"`
|
||||
Shortcuts []Shortcut `json:"shortcuts,omitempty"`
|
||||
|
||||
// Experimental features (uncomment if needed)
|
||||
FileHandlers []FileHandler `json:"file_handlers,omitempty"`
|
||||
ProtocolHandlers []ProtocolHandler `json:"protocol_handlers,omitempty"`
|
||||
}
|
||||
|
||||
type FileHandler struct {
|
||||
Action string `json:"action"`
|
||||
Accept map[string][]string `json:"accept"`
|
||||
}
|
||||
|
||||
type LaunchHandler struct {
|
||||
Action string `json:"action"`
|
||||
}
|
||||
|
||||
type IconDefinition struct {
|
||||
Src string `json:"src"`
|
||||
Sizes string `json:"sizes"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Purpose string `json:"purpose,omitempty"`
|
||||
}
|
||||
|
||||
type ProtocolHandler struct {
|
||||
Scheme string `json:"scheme"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type RelatedApplication struct {
|
||||
Platform string `json:"platform"`
|
||||
URL string `json:"url,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type Shortcut struct {
|
||||
Name string `json:"name"`
|
||||
ShortName string `json:"short_name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
URL string `json:"url"`
|
||||
Icons []IconDefinition `json:"icons,omitempty"`
|
||||
}
|
||||
|
||||
type ServiceWorker struct {
|
||||
Scope string `json:"scope"`
|
||||
Src string `json:"src"`
|
||||
UseCache bool `json:"use_cache"`
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/onsonr/sonr/app/vault/types"
|
||||
"github.com/onsonr/sonr/pkg/common/models"
|
||||
)
|
||||
|
||||
// DefaultSchema returns the default schema
|
||||
func DefaultSchema() *types.Schema {
|
||||
return &types.Schema{
|
||||
Version: SchemaVersion,
|
||||
Account: getSchema(&models.Account{}),
|
||||
Asset: getSchema(&models.Asset{}),
|
||||
Chain: getSchema(&models.Chain{}),
|
||||
Credential: getSchema(&models.Credential{}),
|
||||
Grant: getSchema(&models.Grant{}),
|
||||
Keyshare: getSchema(&models.Keyshare{}),
|
||||
Profile: getSchema(&models.Profile{}),
|
||||
}
|
||||
}
|
||||
|
||||
func getSchema(structType interface{}) string {
|
||||
t := reflect.TypeOf(structType)
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Struct {
|
||||
return ""
|
||||
}
|
||||
|
||||
var fields []string
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
fieldName := toCamelCase(field.Name)
|
||||
fields = append(fields, fieldName)
|
||||
}
|
||||
|
||||
// Add "++" at the beginning, separated by a comma
|
||||
return "++, " + strings.Join(fields, ", ")
|
||||
}
|
||||
|
||||
func toCamelCase(s string) string {
|
||||
if s == "" {
|
||||
return s
|
||||
}
|
||||
if len(s) == 1 {
|
||||
return strings.ToLower(s)
|
||||
}
|
||||
return strings.ToLower(s[:1]) + s[1:]
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ipfs/boxo/files"
|
||||
"github.com/onsonr/sonr/app/gateway/config/internal"
|
||||
"github.com/onsonr/sonr/app/vault/types"
|
||||
)
|
||||
|
||||
const SchemaVersion = 1
|
||||
const (
|
||||
AppManifestFileName = "app.webmanifest"
|
||||
DWNConfigFileName = "dwn.json"
|
||||
IndexHTMLFileName = "index.html"
|
||||
MainJSFileName = "main.js"
|
||||
ServiceWorkerFileName = "sw.js"
|
||||
)
|
||||
|
||||
// spawnVaultDirectory creates a new directory with the default files
|
||||
func NewFS(cfg *types.Config) (files.Directory, error) {
|
||||
manifestBz, err := newWebManifestBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cnfBz, err := json.Marshal(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return files.NewMapDirectory(map[string]files.Node{
|
||||
AppManifestFileName: files.NewBytesFile(manifestBz),
|
||||
DWNConfigFileName: files.NewBytesFile(cnfBz),
|
||||
IndexHTMLFileName: files.NewBytesFile(internal.IndexHTML),
|
||||
MainJSFileName: files.NewBytesFile(internal.MainJS),
|
||||
ServiceWorkerFileName: files.NewBytesFile(internal.WorkerJS),
|
||||
}), nil
|
||||
}
|
||||
|
||||
// GetVaultConfig returns the default vault config
|
||||
func GetVaultConfig(addr string, ucanCID string) *types.Config {
|
||||
return &types.Config{
|
||||
MotrToken: ucanCID,
|
||||
MotrAddress: addr,
|
||||
IpfsGatewayUrl: "http://localhost:80",
|
||||
SonrApiUrl: "http://localhost:1317",
|
||||
SonrRpcUrl: "http://localhost:26657",
|
||||
SonrChainId: "sonr-testnet-1",
|
||||
VaultSchema: DefaultSchema(),
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/pages/index"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/session"
|
||||
"github.com/onsonr/sonr/pkg/common/response"
|
||||
)
|
||||
|
||||
func HandleIndex(c echo.Context) error {
|
||||
if isExpired(c) {
|
||||
return response.TemplEcho(c, index.ReturningView())
|
||||
}
|
||||
return response.TemplEcho(c, index.InitialView())
|
||||
}
|
||||
|
||||
// ╭─────────────────────────────────────────────────────────╮
|
||||
// │ Utility Functions │
|
||||
// ╰─────────────────────────────────────────────────────────╯
|
||||
|
||||
// Initial users have no authorization, user handle, or vault address
|
||||
func isInitial(c echo.Context) bool {
|
||||
sess, err := session.Get(c)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
data := sess.Session()
|
||||
return data.UserHandle == "" && data.VaultAddress == ""
|
||||
}
|
||||
|
||||
// Expired users have either a user handle or vault address
|
||||
func isExpired(c echo.Context) bool {
|
||||
sess, err := session.Get(c)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
data := sess.Session()
|
||||
return data.UserHandle != "" || data.VaultAddress != ""
|
||||
}
|
||||
|
||||
// Returning users have a valid authorization, and either a user handle or vault address
|
||||
func isReturning(c echo.Context) bool {
|
||||
sess, err := session.Get(c)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
data := sess.Session()
|
||||
return data.UserHandle != "" && data.VaultAddress != ""
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func HandleLogin(c echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// func LoginHandler(c echo.Context) error {
|
||||
// options := PublicKeyCredentialRequestOptions{
|
||||
// Challenge: "your-challenge-base64url",
|
||||
// RpID: "yourdomain.com",
|
||||
// Timeout: 60000,
|
||||
// AllowCredentials: []CredentialDescriptor{
|
||||
// {
|
||||
// Type: "public-key",
|
||||
// ID: "credential-id-base64url",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// return GetCredentials(c, options)
|
||||
// }
|
||||
@@ -1,98 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/database"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/pages/register"
|
||||
"github.com/onsonr/sonr/crypto/mpc"
|
||||
"github.com/onsonr/sonr/pkg/common/response"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/forms"
|
||||
)
|
||||
|
||||
func HandleRegisterView(c echo.Context) error {
|
||||
dat := forms.CreateProfileData{
|
||||
FirstNumber: 1,
|
||||
LastNumber: 2,
|
||||
}
|
||||
return response.TemplEcho(c, register.ProfileFormView(dat))
|
||||
}
|
||||
|
||||
func HandleRegisterStart(c echo.Context) error {
|
||||
challenge, _ := protocol.CreateChallenge()
|
||||
handle := c.FormValue("handle")
|
||||
firstName := c.FormValue("first_name")
|
||||
lastName := c.FormValue("last_name")
|
||||
|
||||
ks, err := mpc.NewKeyset()
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
dat := forms.RegisterPasskeyData{
|
||||
Address: ks.Address(),
|
||||
Handle: handle,
|
||||
Name: fmt.Sprintf("%s %s", firstName, lastName),
|
||||
Challenge: challenge.String(),
|
||||
CreationBlock: "00001",
|
||||
}
|
||||
return response.TemplEcho(c, register.LinkCredentialView(dat))
|
||||
}
|
||||
|
||||
func HandleRegisterFinish(c echo.Context) error {
|
||||
// Get the raw credential JSON string
|
||||
credentialJSON := c.FormValue("credential")
|
||||
if credentialJSON == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "missing credential data")
|
||||
}
|
||||
cred := database.Credential{}
|
||||
// Unmarshal the credential JSON
|
||||
if err := json.Unmarshal([]byte(credentialJSON), &cred); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("invalid credential format: %v", err))
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if cred.ID == "" || cred.RawID == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "missing credential ID")
|
||||
}
|
||||
if cred.Type != "public-key" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid credential type")
|
||||
}
|
||||
if cred.Response.AttestationObject == "" || cred.Response.ClientDataJSON == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "missing attestation data")
|
||||
}
|
||||
|
||||
// Decode attestation object and client data
|
||||
attestationObj, err := base64.RawURLEncoding.DecodeString(cred.Response.AttestationObject)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid attestation object encoding")
|
||||
}
|
||||
|
||||
clientData, err := base64.RawURLEncoding.DecodeString(cred.Response.ClientDataJSON)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid client data encoding")
|
||||
}
|
||||
|
||||
// Log detailed credential information
|
||||
fmt.Printf("Credential Details:\n"+
|
||||
"ID: %s\n"+
|
||||
"Raw ID: %s\n"+
|
||||
"Type: %s\n"+
|
||||
"Authenticator Attachment: %s\n"+
|
||||
"Transports: %v\n"+
|
||||
"Attestation Object Size: %d bytes\n"+
|
||||
"Client Data Size: %d bytes\n",
|
||||
cred.ID,
|
||||
cred.RawID,
|
||||
cred.Type,
|
||||
cred.AuthenticatorAttachment,
|
||||
cred.Transports,
|
||||
len(attestationObj),
|
||||
len(clientData))
|
||||
|
||||
return response.TemplEcho(c, register.LoadingVaultView())
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package handlers
|
||||
|
||||
//
|
||||
// type SpawnVaultRequest struct {
|
||||
// Name string `json:"name"`
|
||||
// }
|
||||
//
|
||||
// func SpawnVault(c echo.Context) error {
|
||||
// ks, err := mpc.NewKeyset()
|
||||
// if err != nil {
|
||||
// return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
// }
|
||||
// src, err := mpc.NewSource(ks)
|
||||
// if err != nil {
|
||||
// return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
// }
|
||||
// tk, err := src.OriginToken()
|
||||
// if err != nil {
|
||||
// return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
// }
|
||||
// // Create the vault keyshare auth token
|
||||
// kscid, err := tk.CID()
|
||||
// if err != nil {
|
||||
// return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
// }
|
||||
// // Create the vault config
|
||||
// dir, err := config.NewFS(config.GetVaultConfig(src.Address(), kscid.String()))
|
||||
// path, err := clients.IPFSAdd(c, dir)
|
||||
// if err != nil {
|
||||
// return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
// }
|
||||
// return c.Redirect(http.StatusFound, path)
|
||||
// }
|
||||
@@ -1,57 +0,0 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidCredentials = echo.NewHTTPError(http.StatusUnauthorized, "Invalid credentials")
|
||||
ErrInvalidSubject = echo.NewHTTPError(http.StatusBadRequest, "Invalid subject")
|
||||
ErrInvalidUser = echo.NewHTTPError(http.StatusBadRequest, "Invalid user")
|
||||
|
||||
ErrUserAlreadyExists = echo.NewHTTPError(http.StatusConflict, "User already exists")
|
||||
ErrUserNotFound = echo.NewHTTPError(http.StatusNotFound, "User not found")
|
||||
)
|
||||
|
||||
// Define the credential structure matching our frontend data
|
||||
type Credential struct {
|
||||
ID string `json:"id"`
|
||||
RawID string `json:"rawId"`
|
||||
Type string `json:"type"`
|
||||
AuthenticatorAttachment string `json:"authenticatorAttachment"`
|
||||
Transports []string `json:"transports"`
|
||||
ClientExtensionResults map[string]interface{} `json:"clientExtensionResults"`
|
||||
Response struct {
|
||||
AttestationObject string `json:"attestationObject"`
|
||||
ClientDataJSON string `json:"clientDataJSON"`
|
||||
} `json:"response"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
Address string `json:"address"`
|
||||
Handle string `json:"handle"`
|
||||
Name string `json:"name"`
|
||||
CID string `json:"cid"`
|
||||
Credentials []*Credential `json:"credentials"`
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
gorm.Model
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
BrowserName string `json:"browserName"`
|
||||
BrowserVersion string `json:"browserVersion"`
|
||||
UserArchitecture string `json:"userArchitecture"`
|
||||
Platform string `json:"platform"`
|
||||
PlatformVersion string `json:"platformVersion"`
|
||||
DeviceModel string `json:"deviceModel"`
|
||||
UserHandle string `json:"userHandle"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastInitial string `json:"lastInitial"`
|
||||
VaultAddress string `json:"vaultAddress"`
|
||||
HumanSum int `json:"humanSum"`
|
||||
Challenge string `json:"challenge"`
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/onsonr/sonr/app/gateway/config"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// InitDB initializes and returns a configured database connection
|
||||
func InitDB(env config.Env) (*gorm.DB, error) {
|
||||
path := formatDBPath(env.GetSqliteFile())
|
||||
db, err := gorm.Open(sqlite.Open(path), &gorm.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Migrate the schema
|
||||
db.AutoMigrate(&Session{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func formatDBPath(path string) string {
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
if home == "" {
|
||||
home = "."
|
||||
}
|
||||
|
||||
configDir := filepath.Join(home, ".config", "hway")
|
||||
if err := os.MkdirAll(configDir, 0o755); err != nil {
|
||||
// If we can't create the directory, fall back to current directory
|
||||
return path
|
||||
}
|
||||
|
||||
return filepath.Join(configDir, path)
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package index
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
templ NoWebauthnErrorView() {
|
||||
@layout.Root("Error | Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
No WebAuthn Devices
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
You don't have any WebAuthn devices connected to your computer.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package index
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
func NoWebauthnErrorView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">No WebAuthn Devices</h1><p class=\"text-lg text-zinc-500\">You don't have any WebAuthn devices connected to your computer.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Error | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,36 +0,0 @@
|
||||
package index
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/text"
|
||||
)
|
||||
|
||||
templ InitialView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
@layout.Container() {
|
||||
@text.Header("Sonr.ID", "The decentralized identity layer for the web.")
|
||||
<div class="pt-3 flex flex-col items-center justify-center h-full">
|
||||
<sl-button hx-target="#container" hx-get="/register" hx-push-url="/register" type="button">
|
||||
<sl-icon slot="prefix" library="sonr" name="sonr"></sl-icon>
|
||||
Get Started
|
||||
<sl-icon slot="suffix" library="sonr" name="arrow-right"></sl-icon>
|
||||
</sl-button>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
templ ReturningView() {
|
||||
@layout.Root("Login | Sonr.ID") {
|
||||
@layout.Container() {
|
||||
@text.Header("Welcome Back!", "Continue with your existing Sonr.ID.")
|
||||
<div class="pt-3 flex flex-col items-center justify-center h-full">
|
||||
<sl-button hx-target="#container" hx-get="/register" type="button">
|
||||
<sl-icon slot="prefix" library="sonr" name="sonr"></sl-icon>
|
||||
Log back in
|
||||
<sl-icon slot="suffix" library="sonr" name="arrow-right"></sl-icon>
|
||||
</sl-button>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package index
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/text"
|
||||
)
|
||||
|
||||
func InitialView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = text.Header("Sonr.ID", "The decentralized identity layer for the web.").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-3 flex flex-col items-center justify-center h-full\"><sl-button hx-target=\"#container\" hx-get=\"/register\" hx-push-url=\"/register\" type=\"button\"><sl-icon slot=\"prefix\" library=\"sonr\" name=\"sonr\"></sl-icon> Get Started <sl-icon slot=\"suffix\" library=\"sonr\" name=\"arrow-right\"></sl-icon></sl-button></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func ReturningView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = text.Header("Welcome Back!", "Continue with your existing Sonr.ID.").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"pt-3 flex flex-col items-center justify-center h-full\"><sl-button hx-target=\"#container\" hx-get=\"/register\" type=\"button\"><sl-icon slot=\"prefix\" library=\"sonr\" name=\"sonr\"></sl-icon> Log back in <sl-icon slot=\"suffix\" library=\"sonr\" name=\"arrow-right\"></sl-icon></sl-button></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Login | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,24 +0,0 @@
|
||||
package login
|
||||
|
||||
type LoginRequest struct {
|
||||
Subject string
|
||||
Action string
|
||||
Origin string
|
||||
Status string
|
||||
Ping string
|
||||
BlockSpeed string
|
||||
BlockHeight string
|
||||
}
|
||||
|
||||
type PublicKeyCredentialRequestOptions struct {
|
||||
Challenge string `json:"challenge"`
|
||||
RpID string `json:"rpId"`
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
UserVerification string `json:"userVerification,omitempty"`
|
||||
AllowCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"`
|
||||
}
|
||||
|
||||
type CredentialDescriptor struct {
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
package register
|
||||
|
||||
type RegisterPasskeyData struct {
|
||||
Address string
|
||||
Handle string
|
||||
Name string
|
||||
Challenge string
|
||||
CreationBlock string
|
||||
}
|
||||
|
||||
templ formRegisterPasskey(action, method string, data RegisterPasskeyData) {
|
||||
<form action={ templ.SafeURL(action) } method={ method } id="passkey-form">
|
||||
<input type="hidden" name="credential" id="credential-data" required/>
|
||||
<sl-card class="card-form gap-4 max-w-lg">
|
||||
<div slot="header">
|
||||
<div class="w-full py-2">
|
||||
@sonrProfile(data.Address, data.Name, data.Handle, data.CreationBlock)
|
||||
</div>
|
||||
</div>
|
||||
<sl-select
|
||||
label="Accounts"
|
||||
value="SNR BTC ETH"
|
||||
help-text="Select Blockchains to connect with your Vault"
|
||||
multiple
|
||||
class="custom-tag py-2"
|
||||
>
|
||||
@cryptoWalletOption("SNR", "Sonr", true)
|
||||
@cryptoWalletOption("BTC", "Bitcoin", true)
|
||||
@cryptoWalletOption("ETH", "Ethereum", true)
|
||||
@cryptoWalletOption("SOL", "Solana", false)
|
||||
@cryptoWalletOption("LTC", "Litecoin", false)
|
||||
@cryptoWalletOption("DOGE", "Dogecoin", false)
|
||||
@cryptoWalletOption("XRP", "Ripple", false)
|
||||
@cryptoWalletOption("OSMO", "Osmosis", false)
|
||||
@cryptoWalletOption("ATOM", "Cosmos", false)
|
||||
@cryptoWalletOption("STARZ", "Stargaze", false)
|
||||
@cryptoWalletOption("AKT", "Akash", false)
|
||||
@cryptoWalletOption("EVMOS", "Evmos", false)
|
||||
@cryptoWalletOption("FIL", "Filecoin", false)
|
||||
@cryptoWalletOption("AXL", "Axelar", false)
|
||||
</sl-select>
|
||||
<script type="module">
|
||||
const select = document.querySelector('.custom-tag');
|
||||
|
||||
select.getTag = (option, index) => {
|
||||
// Use the same icon used in the <sl-option>
|
||||
const name = option.querySelector('sl-icon[slot="prefix"]').name;
|
||||
|
||||
// You can return a string, a Lit Template, or an HTMLElement here
|
||||
return `
|
||||
<sl-tag removable>
|
||||
<sl-icon name="${name}" library="crypto" style="padding-inline-end: .5rem;"></sl-icon>
|
||||
${option.getTextLabel()}
|
||||
</sl-tag>
|
||||
`;
|
||||
};
|
||||
</script>
|
||||
<div slot="footer" class="space-y-2">
|
||||
@passkeyDropzone(data.Address, data.Handle, data.Challenge)
|
||||
<sl-button href="/" style="width: 100%;" outline>
|
||||
<sl-icon slot="prefix" name="x-lg"></sl-icon>
|
||||
Cancel
|
||||
</sl-button>
|
||||
</div>
|
||||
<style>
|
||||
.card-form [slot='footer'] {
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</sl-card>
|
||||
</form>
|
||||
}
|
||||
|
||||
templ passkeyDropzone(addr string, userHandle string, challenge string) {
|
||||
<sl-button style="width: 100%;" onclick={ createPasskey(addr, userHandle, challenge) }>
|
||||
<sl-icon slot="prefix" name="passkey" library="sonr" style="font-size: 24px;" class="text-neutral-500"></sl-icon>
|
||||
Register Passkey
|
||||
</sl-button>
|
||||
}
|
||||
|
||||
script createPasskey(userId string, userHandle string, challenge string) {
|
||||
const publicKey = {
|
||||
challenge: Uint8Array.from(challenge, (c) => c.charCodeAt(0)),
|
||||
rp: {
|
||||
name: "Sonr.ID",
|
||||
},
|
||||
user: {
|
||||
// Assuming that userId is ASCII-only
|
||||
id: Uint8Array.from(userId, (c) => c.charCodeAt(0)),
|
||||
name: userId,
|
||||
displayName: userHandle,
|
||||
},
|
||||
pubKeyCredParams: [
|
||||
{
|
||||
type: "public-key",
|
||||
alg: -7, // "ES256"
|
||||
},
|
||||
{
|
||||
type: "public-key",
|
||||
alg: -257, // "RS256"
|
||||
},
|
||||
],
|
||||
authenticatorSelection: {
|
||||
userVerification: "required",
|
||||
residentKey: "required",
|
||||
authenticatorAttachment: "platform",
|
||||
},
|
||||
timeout: 60000, // 1 minute
|
||||
extensions: {
|
||||
payment: {
|
||||
isPayment: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
// Helper function to convert ArrayBuffer to Base64URL string
|
||||
function arrayBufferToBase64URL(buffer) {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
let str = '';
|
||||
bytes.forEach(byte => { str += String.fromCharCode(byte) });
|
||||
return btoa(str)
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '');
|
||||
}
|
||||
|
||||
navigator.credentials
|
||||
.create({ publicKey })
|
||||
.then((newCredentialInfo) => {
|
||||
if (!(newCredentialInfo instanceof PublicKeyCredential)) {
|
||||
throw new Error('Received credential is not a PublicKeyCredential');
|
||||
}
|
||||
|
||||
const response = newCredentialInfo.response;
|
||||
if (!(response instanceof AuthenticatorAttestationResponse)) {
|
||||
throw new Error('Response is not an AuthenticatorAttestationResponse');
|
||||
}
|
||||
|
||||
// Convert the credential data to a cross-platform compatible format
|
||||
const credentialJSON = {
|
||||
id: newCredentialInfo.id,
|
||||
rawId: arrayBufferToBase64URL(newCredentialInfo.rawId),
|
||||
type: newCredentialInfo.type,
|
||||
authenticatorAttachment: newCredentialInfo.authenticatorAttachment || null,
|
||||
transports: Array.isArray(response.getTransports) ? response.getTransports() : [],
|
||||
clientExtensionResults: newCredentialInfo.getClientExtensionResults(),
|
||||
response: {
|
||||
attestationObject: arrayBufferToBase64URL(response.attestationObject),
|
||||
clientDataJSON: arrayBufferToBase64URL(response.clientDataJSON)
|
||||
}
|
||||
};
|
||||
|
||||
// Set the form value with the stringified credential data
|
||||
const credentialInput = document.getElementById('credential-data');
|
||||
credentialInput.value = JSON.stringify(credentialJSON);
|
||||
|
||||
// Submit the form
|
||||
const form = document.getElementById('passkey-form');
|
||||
form.submit();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Passkey creation failed:', err);
|
||||
alert(`Failed to create passkey: ${err.message || 'Unknown error'}`);
|
||||
});
|
||||
}
|
||||
|
||||
templ sonrProfile(addr string, name string, handle string, creationBlock string) {
|
||||
<div class="profile-card min-w-[320px]">
|
||||
<div class="text-white max-w-xs my-auto mx-auto bg-gradient-to-r from-cyan-700 to-cyan-300 p-4 py-5 px-5 rounded-xl">
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<h2>sonr-testnet-1</h2>
|
||||
<p class="text-2xl font-bold">{ handle }</p>
|
||||
</div>
|
||||
<div class="flex items-center opacity-60">
|
||||
<sl-icon style="font-size: 52px;" library="sonr" name="sonr-fill"></sl-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 flex justify-between items-center w-52">
|
||||
<span class="text-lg font-mono">{ shortenAddress(addr) }</span>
|
||||
</div>
|
||||
<div class="flex justify-between mt-5 w-48 ">
|
||||
<div>
|
||||
<h3 class="text-xs">Block Created </h3>
|
||||
<p class="font-bold"><span>#</span>{ creationBlock }</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xs">Issued to</h3>
|
||||
<p class="font-bold">{ name }</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ cryptoWalletOption(ticker string, name string, isDefault bool) {
|
||||
if isDefault {
|
||||
<sl-option value={ ticker } selected disabled>
|
||||
<sl-icon slot="prefix" name={ ticker } library="crypto"></sl-icon>
|
||||
{ name }
|
||||
</sl-option>
|
||||
<sl-divider></sl-divider>
|
||||
} else {
|
||||
<sl-option value={ ticker }>
|
||||
<sl-icon slot="prefix" name={ ticker } library="crypto"></sl-icon>
|
||||
{ name }
|
||||
</sl-option>
|
||||
<sl-divider></sl-divider>
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to shorten address
|
||||
func shortenAddress(address string) string {
|
||||
if len(address) <= 20 {
|
||||
return address
|
||||
}
|
||||
return address[:16] + "..." + address[len(address)-4:]
|
||||
}
|
||||
@@ -1,482 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package register
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
type RegisterPasskeyData struct {
|
||||
Address string
|
||||
Handle string
|
||||
Name string
|
||||
Challenge string
|
||||
CreationBlock string
|
||||
}
|
||||
|
||||
func formRegisterPasskey(action, method string, data RegisterPasskeyData) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_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("<form action=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 templ.SafeURL = templ.SafeURL(action)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var2)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" method=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(method)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 12, Col: 55}
|
||||
}
|
||||
_, 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("\" id=\"passkey-form\"><input type=\"hidden\" name=\"credential\" id=\"credential-data\" required> <sl-card class=\"card-form gap-4 max-w-lg\"><div slot=\"header\"><div class=\"w-full py-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = sonrProfile(data.Address, data.Name, data.Handle, data.CreationBlock).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div><sl-select label=\"Accounts\" value=\"SNR BTC ETH\" help-text=\"Select Blockchains to connect with your Vault\" multiple class=\"custom-tag py-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("SNR", "Sonr", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("BTC", "Bitcoin", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("ETH", "Ethereum", true).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("SOL", "Solana", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("LTC", "Litecoin", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("DOGE", "Dogecoin", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("XRP", "Ripple", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("OSMO", "Osmosis", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("ATOM", "Cosmos", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("STARZ", "Stargaze", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("AKT", "Akash", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("EVMOS", "Evmos", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("FIL", "Filecoin", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = cryptoWalletOption("AXL", "Axelar", false).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</sl-select><script type=\"module\">\n const select = document.querySelector('.custom-tag');\n\n select.getTag = (option, index) => {\n // Use the same icon used in the <sl-option>\n const name = option.querySelector('sl-icon[slot=\"prefix\"]').name;\n\n // You can return a string, a Lit Template, or an HTMLElement here\n return `\n <sl-tag removable>\n <sl-icon name=\"${name}\" library=\"crypto\" style=\"padding-inline-end: .5rem;\"></sl-icon>\n ${option.getTextLabel()}\n </sl-tag>\n `;\n };\n </script><div slot=\"footer\" class=\"space-y-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = passkeyDropzone(data.Address, data.Handle, data.Challenge).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-button href=\"/\" style=\"width: 100%;\" outline><sl-icon slot=\"prefix\" name=\"x-lg\"></sl-icon> Cancel</sl-button></div><style>\n \t\t.card-form [slot='footer'] {\n \t\tjustify-content: space-evenly;\n \t\talign-items: center;\n \t\t}\n\t\t</style></sl-card></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func passkeyDropzone(addr string, userHandle string, challenge 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_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, createPasskey(addr, userHandle, challenge))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-button style=\"width: 100%;\" onclick=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 templ.ComponentScript = createPasskey(addr, userHandle, challenge)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5.Call)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><sl-icon slot=\"prefix\" name=\"passkey\" library=\"sonr\" style=\"font-size: 24px;\" class=\"text-neutral-500\"></sl-icon> Register Passkey</sl-button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func createPasskey(userId string, userHandle string, challenge string) templ.ComponentScript {
|
||||
return templ.ComponentScript{
|
||||
Name: `__templ_createPasskey_fc87`,
|
||||
Function: `function __templ_createPasskey_fc87(userId, userHandle, challenge){const publicKey = {
|
||||
challenge: Uint8Array.from(challenge, (c) => c.charCodeAt(0)),
|
||||
rp: {
|
||||
name: "Sonr.ID",
|
||||
},
|
||||
user: {
|
||||
// Assuming that userId is ASCII-only
|
||||
id: Uint8Array.from(userId, (c) => c.charCodeAt(0)),
|
||||
name: userId,
|
||||
displayName: userHandle,
|
||||
},
|
||||
pubKeyCredParams: [
|
||||
{
|
||||
type: "public-key",
|
||||
alg: -7, // "ES256"
|
||||
},
|
||||
{
|
||||
type: "public-key",
|
||||
alg: -257, // "RS256"
|
||||
},
|
||||
],
|
||||
authenticatorSelection: {
|
||||
userVerification: "required",
|
||||
residentKey: "required",
|
||||
authenticatorAttachment: "platform",
|
||||
},
|
||||
timeout: 60000, // 1 minute
|
||||
extensions: {
|
||||
payment: {
|
||||
isPayment: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
// Helper function to convert ArrayBuffer to Base64URL string
|
||||
function arrayBufferToBase64URL(buffer) {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
let str = '';
|
||||
bytes.forEach(byte => { str += String.fromCharCode(byte) });
|
||||
return btoa(str)
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=/g, '');
|
||||
}
|
||||
|
||||
navigator.credentials
|
||||
.create({ publicKey })
|
||||
.then((newCredentialInfo) => {
|
||||
if (!(newCredentialInfo instanceof PublicKeyCredential)) {
|
||||
throw new Error('Received credential is not a PublicKeyCredential');
|
||||
}
|
||||
|
||||
const response = newCredentialInfo.response;
|
||||
if (!(response instanceof AuthenticatorAttestationResponse)) {
|
||||
throw new Error('Response is not an AuthenticatorAttestationResponse');
|
||||
}
|
||||
|
||||
// Convert the credential data to a cross-platform compatible format
|
||||
const credentialJSON = {
|
||||
id: newCredentialInfo.id,
|
||||
rawId: arrayBufferToBase64URL(newCredentialInfo.rawId),
|
||||
type: newCredentialInfo.type,
|
||||
authenticatorAttachment: newCredentialInfo.authenticatorAttachment || null,
|
||||
transports: Array.isArray(response.getTransports) ? response.getTransports() : [],
|
||||
clientExtensionResults: newCredentialInfo.getClientExtensionResults(),
|
||||
response: {
|
||||
attestationObject: arrayBufferToBase64URL(response.attestationObject),
|
||||
clientDataJSON: arrayBufferToBase64URL(response.clientDataJSON)
|
||||
}
|
||||
};
|
||||
|
||||
// Set the form value with the stringified credential data
|
||||
const credentialInput = document.getElementById('credential-data');
|
||||
credentialInput.value = JSON.stringify(credentialJSON);
|
||||
|
||||
// Submit the form
|
||||
const form = document.getElementById('passkey-form');
|
||||
form.submit();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Passkey creation failed:', err);
|
||||
alert(` + "`" + `Failed to create passkey: ${err.message || 'Unknown error'}` + "`" + `);
|
||||
});
|
||||
}`,
|
||||
Call: templ.SafeScript(`__templ_createPasskey_fc87`, userId, userHandle, challenge),
|
||||
CallInline: templ.SafeScriptInline(`__templ_createPasskey_fc87`, userId, userHandle, challenge),
|
||||
}
|
||||
}
|
||||
|
||||
func sonrProfile(addr string, name string, handle string, creationBlock 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_Var6 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var6 == nil {
|
||||
templ_7745c5c3_Var6 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"profile-card min-w-[320px]\"><div class=\"text-white max-w-xs my-auto mx-auto bg-gradient-to-r from-cyan-700 to-cyan-300 p-4 py-5 px-5 rounded-xl\"><div class=\"flex justify-between\"><div><h2>sonr-testnet-1</h2><p class=\"text-2xl font-bold\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(handle)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 173, Col: 43}
|
||||
}
|
||||
_, 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("</p></div><div class=\"flex items-center opacity-60\"><sl-icon style=\"font-size: 52px;\" library=\"sonr\" name=\"sonr-fill\"></sl-icon></div></div><div class=\"mt-5 flex justify-between items-center w-52\"><span class=\"text-lg font-mono\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(shortenAddress(addr))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 180, Col: 58}
|
||||
}
|
||||
_, 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("</span></div><div class=\"flex justify-between mt-5 w-48 \"><div><h3 class=\"text-xs\">Block Created </h3><p class=\"font-bold\"><span>#</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(creationBlock)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 185, Col: 55}
|
||||
}
|
||||
_, 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("</p></div><div><h3 class=\"text-xs\">Issued to</h3><p class=\"font-bold\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 189, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func cryptoWalletOption(ticker string, name string, isDefault bool) 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_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if isDefault {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-option value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(ticker)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 198, Col: 27}
|
||||
}
|
||||
_, 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("\" selected disabled><sl-icon slot=\"prefix\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(ticker)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 199, Col: 39}
|
||||
}
|
||||
_, 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("\" library=\"crypto\"></sl-icon> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 200, Col: 9}
|
||||
}
|
||||
_, 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("</sl-option> <sl-divider></sl-divider>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-option value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(ticker)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 204, Col: 27}
|
||||
}
|
||||
_, 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("\"><sl-icon slot=\"prefix\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 string
|
||||
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(ticker)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 205, Col: 39}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" library=\"crypto\"></sl-icon> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 string
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/creds.templ`, Line: 206, Col: 9}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</sl-option> <sl-divider></sl-divider>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// Helper function to shorten address
|
||||
func shortenAddress(address string) string {
|
||||
if len(address) <= 20 {
|
||||
return address
|
||||
}
|
||||
return address[:16] + "..." + address[len(address)-4:]
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,20 +0,0 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"github.com/a-h/templ"
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
)
|
||||
|
||||
type LinkCredentialRequest struct {
|
||||
Platform string `json:"platform"`
|
||||
Handle string `json:"handle"`
|
||||
DeviceModel string `json:"deviceModel"`
|
||||
Architecture string `json:"architecture"`
|
||||
Address string `json:"address"`
|
||||
RegisterOptions protocol.PublicKeyCredentialCreationOptions `json:"registerOptions"`
|
||||
}
|
||||
|
||||
func (r LinkCredentialRequest) GetCredentialOptions() string {
|
||||
opts, _ := templ.JSONString(r.RegisterOptions)
|
||||
return opts
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/text"
|
||||
)
|
||||
|
||||
templ ProfileFormView(data CreateProfileData) {
|
||||
@layout.Root("Create Profile | Sonr.ID") {
|
||||
@layout.Container() {
|
||||
@text.Header("Basic Info", "Tell us a little about yourself.")
|
||||
@formCreateProfile("/register/start", "POST", data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
templ LinkCredentialView(data RegisterPasskeyData) {
|
||||
@layout.Root("Register | Sonr.ID") {
|
||||
@layout.Container() {
|
||||
@text.Header("Link a PassKey", "This will be used to login to your vault.")
|
||||
@formRegisterPasskey("/register/finish", "POST", data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
templ LoadingVaultView() {
|
||||
@layout.Root("Loading... | Sonr.ID") {
|
||||
@layout.Container() {
|
||||
@text.Header("Loading Vault", "This will be used to login to your vault.")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package register
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/text"
|
||||
)
|
||||
|
||||
func ProfileFormView(data CreateProfileData) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = text.Header("Basic Info", "Tell us a little about yourself.").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = formCreateProfile("/register/start", "POST", data).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Create Profile | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func LinkCredentialView(data RegisterPasskeyData) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = text.Header("Link a PassKey", "This will be used to login to your vault.").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = formRegisterPasskey("/register/finish", "POST", data).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Register | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func LoadingVaultView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var7 == nil {
|
||||
templ_7745c5c3_Var7 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var9 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = text.Header("Loading Vault", "This will be used to login to your vault.").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Container().Render(templ.WithChildren(ctx, templ_7745c5c3_Var9), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Loading... | Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,78 +0,0 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
)
|
||||
|
||||
type CreateProfileData struct {
|
||||
TurnstileSiteKey string
|
||||
FirstNumber int
|
||||
LastNumber int
|
||||
}
|
||||
|
||||
func (d CreateProfileData) IsHumanLabel() string {
|
||||
return fmt.Sprintf("What is %d + %d?", d.FirstNumber, d.LastNumber)
|
||||
}
|
||||
|
||||
templ formCreateProfile(action string, method string, data CreateProfileData) {
|
||||
<form action={ templ.SafeURL(action) } method={ method }>
|
||||
<sl-card class="card-form gap-4 w-full max-w-lg mx-auto px-4 sm:px-6">
|
||||
<div slot="header">
|
||||
<div class="w-full py-1">
|
||||
<sl-progress-bar value="50"></sl-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
@layout.Rows() {
|
||||
<sl-input name="first_name" placeholder="Satoshi" type="text" label="First Name" required autofocus></sl-input>
|
||||
<sl-input name="last_name" placeholder="N" maxlength="1" type="text" label="Last Initial"></sl-input>
|
||||
}
|
||||
@layout.Spacer()
|
||||
<sl-input name="handle" placeholder="digitalgold" type="text" label="Handle" minlength="4" maxlength="12" required>
|
||||
<div slot="prefix">
|
||||
<sl-icon name="at-sign" library="sonr"></sl-icon>
|
||||
</div>
|
||||
</sl-input>
|
||||
@layout.Spacer()
|
||||
<sl-range name="is_human" label={ data.IsHumanLabel() } help-text="Prove you are a human." min="0" max="9" step="1"></sl-range>
|
||||
<div slot="footer">
|
||||
<sl-button href="/" outline>
|
||||
<sl-icon slot="prefix" name="arrow-left" library="sonr"></sl-icon>
|
||||
Cancel
|
||||
</sl-button>
|
||||
<sl-button type="submit">
|
||||
Next
|
||||
<sl-icon slot="suffix" name="arrow-right" library="sonr"></sl-icon>
|
||||
</sl-button>
|
||||
</div>
|
||||
<style>
|
||||
.card-form {
|
||||
margin: 1rem;
|
||||
}
|
||||
.card-form [slot='footer'] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.card-form {
|
||||
margin: 0.5rem;
|
||||
}
|
||||
.card-form [slot='footer'] {
|
||||
flex-direction: column-reverse;
|
||||
width: 100%;
|
||||
}
|
||||
.card-form [slot='footer'] sl-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</sl-card>
|
||||
</form>
|
||||
}
|
||||
|
||||
// ╭──────────────────────────────────────────────────────╮
|
||||
// │ Passkey Components │
|
||||
// ╰──────────────────────────────────────────────────────╯
|
||||
@@ -1,131 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package register
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
)
|
||||
|
||||
type CreateProfileData struct {
|
||||
TurnstileSiteKey string
|
||||
FirstNumber int
|
||||
LastNumber int
|
||||
}
|
||||
|
||||
func (d CreateProfileData) IsHumanLabel() string {
|
||||
return fmt.Sprintf("What is %d + %d?", d.FirstNumber, d.LastNumber)
|
||||
}
|
||||
|
||||
func formCreateProfile(action string, method string, data CreateProfileData) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form action=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 templ.SafeURL = templ.SafeURL(action)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var2)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" method=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(method)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/profile.templ`, Line: 19, Col: 55}
|
||||
}
|
||||
_, 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("\"><sl-card class=\"card-form gap-4 w-full max-w-lg mx-auto px-4 sm:px-6\"><div slot=\"header\"><div class=\"w-full py-1\"><sl-progress-bar value=\"50\"></sl-progress-bar></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-input name=\"first_name\" placeholder=\"Satoshi\" type=\"text\" label=\"First Name\" required autofocus></sl-input> <sl-input name=\"last_name\" placeholder=\"N\" maxlength=\"1\" type=\"text\" label=\"Last Initial\"></sl-input>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Rows().Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = layout.Spacer().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-input name=\"handle\" placeholder=\"digitalgold\" type=\"text\" label=\"Handle\" minlength=\"4\" maxlength=\"12\" required><div slot=\"prefix\"><sl-icon name=\"at-sign\" library=\"sonr\"></sl-icon></div></sl-input>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = layout.Spacer().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<sl-range name=\"is_human\" label=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.IsHumanLabel())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `app/gateway/internal/pages/register/profile.templ`, Line: 37, Col: 56}
|
||||
}
|
||||
_, 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("\" help-text=\"Prove you are a human.\" min=\"0\" max=\"9\" step=\"1\"></sl-range><div slot=\"footer\"><sl-button href=\"/\" outline><sl-icon slot=\"prefix\" name=\"arrow-left\" library=\"sonr\"></sl-icon> Cancel</sl-button> <sl-button type=\"submit\">Next <sl-icon slot=\"suffix\" name=\"arrow-right\" library=\"sonr\"></sl-icon></sl-button></div><style>\n\t\t\t\t.card-form {\n\t\t\t\t\tmargin: 1rem;\n\t\t\t\t}\n\t\t\t\t.card-form [slot='footer'] {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tjustify-content: space-between;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tflex-wrap: wrap;\n\t\t\t\t\tgap: 1rem;\n\t\t\t\t}\n\t\t\t\t@media (max-width: 640px) {\n\t\t\t\t\t.card-form {\n\t\t\t\t\t\tmargin: 0.5rem;\n\t\t\t\t\t}\n\t\t\t\t\t.card-form [slot='footer'] {\n\t\t\t\t\t\tflex-direction: column-reverse;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t}\n\t\t\t\t\t.card-form [slot='footer'] sl-button {\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</style></sl-card></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// ╭──────────────────────────────────────────────────────╮
|
||||
// │ Passkey Components │
|
||||
// ╰──────────────────────────────────────────────────────╯
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,102 +0,0 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/database"
|
||||
"github.com/onsonr/sonr/pkg/common"
|
||||
"github.com/segmentio/ksuid"
|
||||
)
|
||||
|
||||
// InitSession initializes or loads an existing session
|
||||
func (s *HTTPContext) InitSession() error {
|
||||
sessionID := s.getOrCreateSessionID()
|
||||
|
||||
// Try to load existing session
|
||||
var sess database.Session
|
||||
result := s.db.Where("id = ?", sessionID).First(&sess)
|
||||
if result.Error != nil {
|
||||
// Create new session if not found
|
||||
bn, bv, arch, plat, platVer, model := extractBrowserInfo(s.Context)
|
||||
sess = database.Session{
|
||||
ID: sessionID,
|
||||
BrowserName: bn,
|
||||
BrowserVersion: bv,
|
||||
UserArchitecture: arch,
|
||||
Platform: plat,
|
||||
PlatformVersion: platVer,
|
||||
DeviceModel: model,
|
||||
}
|
||||
if err := s.db.Create(&sess).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.sess = &sess
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *HTTPContext) getOrCreateSessionID() string {
|
||||
if ok := common.CookieExists(s.Context, common.SessionID); !ok {
|
||||
sessionID := ksuid.New().String()
|
||||
common.WriteCookie(s.Context, common.SessionID, sessionID)
|
||||
return sessionID
|
||||
}
|
||||
|
||||
sessionID, err := common.ReadCookie(s.Context, common.SessionID)
|
||||
if err != nil {
|
||||
sessionID = ksuid.New().String()
|
||||
common.WriteCookie(s.Context, common.SessionID, sessionID)
|
||||
}
|
||||
return sessionID
|
||||
}
|
||||
|
||||
func extractBrowserInfo(c echo.Context) (string, string, string, string, string, string) {
|
||||
// Extract all relevant headers
|
||||
browserName := common.HeaderRead(c, common.UserAgent)
|
||||
arch := common.HeaderRead(c, common.Architecture)
|
||||
platform := common.HeaderRead(c, common.Platform)
|
||||
platformVer := common.HeaderRead(c, common.PlatformVersion)
|
||||
model := common.HeaderRead(c, common.Model)
|
||||
fullVersionList := common.HeaderRead(c, common.FullVersionList)
|
||||
|
||||
// Default values if headers are empty
|
||||
if browserName == "" {
|
||||
browserName = "N/A"
|
||||
}
|
||||
if arch == "" {
|
||||
arch = "unknown"
|
||||
}
|
||||
if platform == "" {
|
||||
platform = "unknown"
|
||||
}
|
||||
if platformVer == "" {
|
||||
platformVer = "unknown"
|
||||
}
|
||||
if model == "" {
|
||||
model = "unknown"
|
||||
}
|
||||
|
||||
// Extract browser version from full version list
|
||||
version := "-1"
|
||||
if fullVersionList != "" {
|
||||
entries := strings.Split(strings.TrimSpace(fullVersionList), ",")
|
||||
for _, entry := range entries {
|
||||
entry = strings.TrimSpace(entry)
|
||||
re := regexp.MustCompile(`"([^"]+)";v="([^"]+)"`)
|
||||
matches := re.FindStringSubmatch(entry)
|
||||
|
||||
if len(matches) == 3 {
|
||||
browserName = matches[1]
|
||||
version = matches[2]
|
||||
if browserName != "Not.A/Brand" &&
|
||||
browserName != "Chromium" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return browserName, version, arch, platform, platformVer, model
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package session
|
||||
@@ -1,53 +0,0 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/app/gateway/config"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/database"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Middleware creates a new session middleware
|
||||
func Middleware(db *gorm.DB, env config.Env) echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
cc := NewHTTPContext(c, db)
|
||||
if err := cc.InitSession(); err != nil {
|
||||
return err
|
||||
}
|
||||
return next(cc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPContext is the context for HTTP endpoints.
|
||||
type HTTPContext struct {
|
||||
echo.Context
|
||||
db *gorm.DB
|
||||
sess *database.Session
|
||||
env config.Env
|
||||
}
|
||||
|
||||
// Get returns the HTTPContext from the echo context
|
||||
func Get(c echo.Context) (*HTTPContext, error) {
|
||||
ctx, ok := c.(*HTTPContext)
|
||||
if !ok {
|
||||
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Session Context not found")
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// NewHTTPContext creates a new session context
|
||||
func NewHTTPContext(c echo.Context, db *gorm.DB) *HTTPContext {
|
||||
return &HTTPContext{
|
||||
Context: c,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// Session returns the current session
|
||||
func (s *HTTPContext) Session() *database.Session {
|
||||
return s.sess
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/database"
|
||||
)
|
||||
|
||||
// ╭───────────────────────────────────────────────────────╮
|
||||
// │ DB Setter Functions │
|
||||
// ╰───────────────────────────────────────────────────────╯
|
||||
|
||||
// SetUserHandle sets the user handle in the session
|
||||
func SetUserHandle(c echo.Context, handle string) error {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sess.Session().UserHandle = handle
|
||||
return sess.db.Save(sess.Session()).Error
|
||||
}
|
||||
|
||||
// SetFirstName sets the first name in the session
|
||||
func SetFirstName(c echo.Context, name string) error {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sess.Session().FirstName = name
|
||||
return sess.db.Save(sess.Session()).Error
|
||||
}
|
||||
|
||||
// SetLastInitial sets the last initial in the session
|
||||
func SetLastInitial(c echo.Context, initial string) error {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sess.Session().LastInitial = initial
|
||||
return sess.db.Save(sess.Session()).Error
|
||||
}
|
||||
|
||||
// SetVaultAddress sets the vault address in the session
|
||||
func SetVaultAddress(c echo.Context, address string) error {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sess.Session().VaultAddress = address
|
||||
return sess.db.Save(sess.Session()).Error
|
||||
}
|
||||
|
||||
// ╭───────────────────────────────────────────────────────╮
|
||||
// │ DB Getter Functions │
|
||||
// ╰───────────────────────────────────────────────────────╯
|
||||
|
||||
// GetID returns the session ID
|
||||
func GetID(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().ID, nil
|
||||
}
|
||||
|
||||
// GetBrowserName returns the browser name
|
||||
func GetBrowserName(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().BrowserName, nil
|
||||
}
|
||||
|
||||
// GetBrowserVersion returns the browser version
|
||||
func GetBrowserVersion(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().BrowserVersion, nil
|
||||
}
|
||||
|
||||
// GetUserArchitecture returns the user architecture
|
||||
func GetUserArchitecture(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().UserArchitecture, nil
|
||||
}
|
||||
|
||||
// GetPlatform returns the platform
|
||||
func GetPlatform(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().Platform, nil
|
||||
}
|
||||
|
||||
// GetPlatformVersion returns the platform version
|
||||
func GetPlatformVersion(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().PlatformVersion, nil
|
||||
}
|
||||
|
||||
// GetDeviceModel returns the device model
|
||||
func GetDeviceModel(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().DeviceModel, nil
|
||||
}
|
||||
|
||||
// GetUserHandle returns the user handle
|
||||
func GetUserHandle(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().UserHandle, nil
|
||||
}
|
||||
|
||||
// GetFirstName returns the first name
|
||||
func GetFirstName(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().FirstName, nil
|
||||
}
|
||||
|
||||
// GetLastInitial returns the last initial
|
||||
func GetLastInitial(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().LastInitial, nil
|
||||
}
|
||||
|
||||
// GetVaultAddress returns the vault address
|
||||
func GetVaultAddress(c echo.Context) (string, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sess.Session().VaultAddress, nil
|
||||
}
|
||||
|
||||
// HandleExists checks if a handle already exists in any session
|
||||
func HandleExists(c echo.Context, handle string) (bool, error) {
|
||||
sess, err := Get(c)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var count int64
|
||||
if err := sess.db.Model(&database.Session{}).Where("user_handle = ?", handle).Count(&count).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Package gateway provides the default routes for the Sonr hway.
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/sonr/app/gateway/config"
|
||||
"github.com/onsonr/sonr/app/gateway/handlers"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/database"
|
||||
"github.com/onsonr/sonr/app/gateway/internal/session"
|
||||
"github.com/onsonr/sonr/pkg/common/response"
|
||||
)
|
||||
|
||||
func RegisterRoutes(e *echo.Echo, env config.Env) error {
|
||||
// Custom error handler for gateway
|
||||
e.HTTPErrorHandler = response.RedirectOnError("http://localhost:3000")
|
||||
|
||||
// Initialize database
|
||||
db, err := database.InitDB(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Inject session middleware with database connection
|
||||
e.Use(session.Middleware(db, env))
|
||||
|
||||
// Register routes
|
||||
e.GET("/", handlers.HandleIndex)
|
||||
e.GET("/register", handlers.HandleRegisterView)
|
||||
e.POST("/register/start", handlers.HandleRegisterStart)
|
||||
e.POST("/register/finish", handlers.HandleRegisterFinish)
|
||||
return nil
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.hway.Gate`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type Config struct {
|
||||
ChainId string `pkl:"chainId" json:"chainId,omitempty"`
|
||||
|
||||
IpfsGatewayUrl string `pkl:"ipfsGatewayUrl" json:"ipfsGatewayUrl,omitempty"`
|
||||
|
||||
LandingUrl string `pkl:"landingUrl" json:"landingUrl,omitempty"`
|
||||
|
||||
AuthProxyUrl string `pkl:"authProxyUrl" json:"authProxyUrl,omitempty"`
|
||||
|
||||
SonrApiUrl string `pkl:"sonrApiUrl" json:"sonrApiUrl,omitempty"`
|
||||
|
||||
SonrRpcUrl string `pkl:"sonrRpcUrl" json:"sonrRpcUrl,omitempty"`
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.hway.Ctx`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type Ctx struct {
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.hway.Gate`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
import "github.com/apple/pkl-go/pkl"
|
||||
|
||||
func init() {
|
||||
pkl.RegisterMapping("sonr.hway.Gate#Config", Config{})
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package vault
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
var (
|
||||
// Global buffer pool to reduce allocations
|
||||
bufferPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
|
||||
// Cached JS globals
|
||||
jsGlobal = js.Global()
|
||||
jsUint8Array = jsGlobal.Get("Uint8Array")
|
||||
jsResponse = jsGlobal.Get("Response")
|
||||
jsPromise = jsGlobal.Get("Promise")
|
||||
jsWasmHTTP = jsGlobal.Get("wasmhttp")
|
||||
)
|
||||
|
||||
// ServeFetch serves HTTP requests with optimized handler management
|
||||
func ServeFetch(handler http.Handler) func() {
|
||||
h := handler
|
||||
if h == nil {
|
||||
h = http.DefaultServeMux
|
||||
}
|
||||
|
||||
// Optimize prefix handling
|
||||
prefix := strings.TrimRight(jsWasmHTTP.Get("path").String(), "/")
|
||||
if prefix != "" {
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle(prefix+"/", http.StripPrefix(prefix, h))
|
||||
h = mux
|
||||
}
|
||||
|
||||
// Create request handler function
|
||||
cb := js.FuncOf(func(_ js.Value, args []js.Value) interface{} {
|
||||
promise, resolve, reject := newPromiseOptimized()
|
||||
|
||||
go handleRequest(h, args[1], resolve, reject)
|
||||
|
||||
return promise
|
||||
})
|
||||
|
||||
jsWasmHTTP.Call("setHandler", cb)
|
||||
return cb.Release
|
||||
}
|
||||
|
||||
// handleRequest processes the request with panic recovery
|
||||
func handleRequest(h http.Handler, jsReq js.Value, resolve, reject func(interface{})) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
var errMsg string
|
||||
if err, ok := r.(error); ok {
|
||||
errMsg = fmt.Sprintf("wasmhttp: panic: %+v", err)
|
||||
} else {
|
||||
errMsg = fmt.Sprintf("wasmhttp: panic: %v", r)
|
||||
}
|
||||
reject(errMsg)
|
||||
}
|
||||
}()
|
||||
|
||||
recorder := newResponseRecorder()
|
||||
h.ServeHTTP(recorder, buildRequest(jsReq))
|
||||
resolve(recorder.jsResponse())
|
||||
}
|
||||
|
||||
// buildRequest creates an http.Request from JS Request
|
||||
func buildRequest(jsReq js.Value) *http.Request {
|
||||
// Get request body
|
||||
arrayBuffer, err := awaitPromiseOptimized(jsReq.Call("arrayBuffer"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create body buffer
|
||||
jsBody := jsUint8Array.New(arrayBuffer)
|
||||
bodyLen := jsBody.Get("length").Int()
|
||||
body := make([]byte, bodyLen)
|
||||
js.CopyBytesToGo(body, jsBody)
|
||||
|
||||
// Create request
|
||||
req := httptest.NewRequest(
|
||||
jsReq.Get("method").String(),
|
||||
jsReq.Get("url").String(),
|
||||
bytes.NewReader(body),
|
||||
)
|
||||
|
||||
// Set headers efficiently
|
||||
headers := jsReq.Get("headers")
|
||||
headersIt := headers.Call("entries")
|
||||
for {
|
||||
entry := headersIt.Call("next")
|
||||
if entry.Get("done").Bool() {
|
||||
break
|
||||
}
|
||||
pair := entry.Get("value")
|
||||
req.Header.Set(pair.Index(0).String(), pair.Index(1).String())
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
// ResponseRecorder with optimized buffer handling
|
||||
type ResponseRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
buffer *bytes.Buffer
|
||||
}
|
||||
|
||||
func newResponseRecorder() *ResponseRecorder {
|
||||
return &ResponseRecorder{
|
||||
ResponseRecorder: httptest.NewRecorder(),
|
||||
buffer: bufferPool.Get().(*bytes.Buffer),
|
||||
}
|
||||
}
|
||||
|
||||
// jsResponse creates a JS Response with optimized memory usage
|
||||
func (rr *ResponseRecorder) jsResponse() js.Value {
|
||||
defer func() {
|
||||
rr.buffer.Reset()
|
||||
bufferPool.Put(rr.buffer)
|
||||
}()
|
||||
|
||||
res := rr.Result()
|
||||
defer res.Body.Close()
|
||||
|
||||
// Prepare response body
|
||||
body := js.Undefined()
|
||||
if res.ContentLength != 0 {
|
||||
if _, err := io.Copy(rr.buffer, res.Body); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bodyBytes := rr.buffer.Bytes()
|
||||
body = jsUint8Array.New(len(bodyBytes))
|
||||
js.CopyBytesToJS(body, bodyBytes)
|
||||
}
|
||||
|
||||
// Prepare response init object
|
||||
init := make(map[string]interface{}, 3)
|
||||
if res.StatusCode != 0 {
|
||||
init["status"] = res.StatusCode
|
||||
}
|
||||
|
||||
if len(res.Header) > 0 {
|
||||
headers := make(map[string]interface{}, len(res.Header))
|
||||
for k, v := range res.Header {
|
||||
if len(v) > 0 {
|
||||
headers[k] = v[0]
|
||||
}
|
||||
}
|
||||
init["headers"] = headers
|
||||
}
|
||||
|
||||
return jsResponse.New(body, init)
|
||||
}
|
||||
|
||||
// newPromiseOptimized creates a new JavaScript Promise with optimized callback handling
|
||||
func newPromiseOptimized() (js.Value, func(interface{}), func(interface{})) {
|
||||
var (
|
||||
resolve func(interface{})
|
||||
reject func(interface{})
|
||||
promiseFunc = js.FuncOf(func(_ js.Value, args []js.Value) interface{} {
|
||||
resolve = func(v interface{}) { args[0].Invoke(v) }
|
||||
reject = func(v interface{}) { args[1].Invoke(v) }
|
||||
return js.Undefined()
|
||||
})
|
||||
)
|
||||
defer promiseFunc.Release()
|
||||
|
||||
return jsPromise.New(promiseFunc), resolve, reject
|
||||
}
|
||||
|
||||
// awaitPromiseOptimized waits for Promise resolution with optimized channel handling
|
||||
func awaitPromiseOptimized(promise js.Value) (js.Value, error) {
|
||||
done := make(chan struct{})
|
||||
var (
|
||||
result js.Value
|
||||
err error
|
||||
)
|
||||
|
||||
thenFunc := js.FuncOf(func(_ js.Value, args []js.Value) interface{} {
|
||||
result = args[0]
|
||||
close(done)
|
||||
return nil
|
||||
})
|
||||
defer thenFunc.Release()
|
||||
|
||||
catchFunc := js.FuncOf(func(_ js.Value, args []js.Value) interface{} {
|
||||
err = js.Error{Value: args[0]}
|
||||
close(done)
|
||||
return nil
|
||||
})
|
||||
defer catchFunc.Release()
|
||||
|
||||
promise.Call("then", thenFunc).Call("catch", catchFunc)
|
||||
<-done
|
||||
|
||||
return result, err
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package handlers
|
||||
@@ -1,23 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func GrantAuthorization(e echo.Context) error {
|
||||
// Implement authorization endpoint using passkey authentication
|
||||
// Store session data in cache
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetJWKS(e echo.Context) error {
|
||||
// Implement token endpoint
|
||||
// Use cached session data for validation
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetToken(e echo.Context) error {
|
||||
// Implement token endpoint
|
||||
// Use cached session data for validation
|
||||
return nil
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func HandleConnect(c echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Login Handlers │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
// LoginSubjectCheck handles the login subject check.
|
||||
func LoginSubjectCheck(e echo.Context) error {
|
||||
return e.JSON(200, "HandleCredentialAssertion")
|
||||
}
|
||||
|
||||
// LoginSubjectStart handles the login subject start.
|
||||
func LoginSubjectStart(e echo.Context) error {
|
||||
opts := &protocol.PublicKeyCredentialRequestOptions{
|
||||
UserVerification: "preferred",
|
||||
Challenge: []byte("challenge"),
|
||||
}
|
||||
return e.JSON(200, opts)
|
||||
}
|
||||
|
||||
// LoginSubjectFinish handles the login subject finish.
|
||||
func LoginSubjectFinish(e echo.Context) error {
|
||||
var crr protocol.CredentialAssertionResponse
|
||||
if err := e.Bind(&crr); err != nil {
|
||||
return err
|
||||
}
|
||||
return e.JSON(200, crr)
|
||||
}
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Register Handlers │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
// RegisterSubjectCheck handles the register subject check.
|
||||
func RegisterSubjectCheck(e echo.Context) error {
|
||||
subject := e.FormValue("subject")
|
||||
return e.JSON(200, subject)
|
||||
}
|
||||
|
||||
// RegisterSubjectStart handles the register subject start.
|
||||
func RegisterSubjectStart(e echo.Context) error {
|
||||
// Get subject and address
|
||||
// subject := e.FormValue("subject")
|
||||
|
||||
// Get challenge
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterSubjectFinish handles the register subject finish.
|
||||
func RegisterSubjectFinish(e echo.Context) error {
|
||||
// Deserialize the JSON into a temporary struct
|
||||
var ccr protocol.CredentialCreationResponse
|
||||
if err := e.Bind(&ccr); err != nil {
|
||||
return err
|
||||
}
|
||||
//
|
||||
// // Parse the CredentialCreationResponse
|
||||
// parsedData, err := ccr.Parse()
|
||||
// if err != nil {
|
||||
// return e.JSON(500, err.Error())
|
||||
// }
|
||||
//
|
||||
// // Create the Credential
|
||||
// // credential := orm.NewCredential(parsedData, e.Request().Host, "")
|
||||
return e.JSON(201, ccr)
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func HandleDash(c echo.Context) error {
|
||||
return c.Render(http.StatusOK, "index.templ", nil)
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
session "github.com/onsonr/sonr/app/vault/internal"
|
||||
"github.com/onsonr/sonr/app/vault/internal/pages/index"
|
||||
"github.com/onsonr/sonr/pkg/common/response"
|
||||
)
|
||||
|
||||
func HandleIndex(c echo.Context) error {
|
||||
if isInitial(c) {
|
||||
return response.TemplEcho(c, index.InitialView())
|
||||
}
|
||||
if isExpired(c) {
|
||||
return response.TemplEcho(c, index.ReturningView())
|
||||
}
|
||||
return c.Render(http.StatusOK, "index.templ", nil)
|
||||
}
|
||||
|
||||
// ╭─────────────────────────────────────────────────────────╮
|
||||
// │ Utility Functions │
|
||||
// ╰─────────────────────────────────────────────────────────╯
|
||||
|
||||
// Initial users have no authorization, user handle, or vault address
|
||||
func isInitial(c echo.Context) bool {
|
||||
noAuth := !session.HasAuthorization(c)
|
||||
noUserHandle := !session.HasUserHandle(c)
|
||||
noVaultAddress := !session.HasVaultAddress(c)
|
||||
return noUserHandle && noVaultAddress && noAuth
|
||||
}
|
||||
|
||||
// Expired users have either a user handle or vault address
|
||||
func isExpired(c echo.Context) bool {
|
||||
noAuth := !session.HasAuthorization(c)
|
||||
hasUserHandle := session.HasUserHandle(c)
|
||||
hasVaultAddress := session.HasVaultAddress(c)
|
||||
return noAuth && hasUserHandle || noAuth && hasVaultAddress
|
||||
}
|
||||
|
||||
// Returning users have a valid authorization, and either a user handle or vault address
|
||||
func isReturning(c echo.Context) bool {
|
||||
hasAuth := session.HasAuthorization(c)
|
||||
hasUserHandle := session.HasUserHandle(c)
|
||||
hasVaultAddress := session.HasVaultAddress(c)
|
||||
return hasAuth && (hasUserHandle || hasVaultAddress)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package handlers
|
||||
@@ -1 +0,0 @@
|
||||
package handlers
|
||||
@@ -1,93 +0,0 @@
|
||||
package handlers
|
||||
|
||||
//
|
||||
// // Constants for supported payment methods
|
||||
// const (
|
||||
// MethodCard = "basic-card"
|
||||
// MethodGooglePay = "https://google.com/pay"
|
||||
// MethodApplePay = "https://apple.com/apple-pay"
|
||||
// MethodSonrWallet = "https://sonr.id/wallet"
|
||||
// )
|
||||
//
|
||||
// // InitiatePayment starts the payment request flow
|
||||
// func InitiatePayment(c echo.Context, request PaymentRequest) error {
|
||||
// return StartPayment(request).Render(c.Request().Context(), c.Response().Writer)
|
||||
// }
|
||||
//
|
||||
// // Helper functions to create payment requests
|
||||
// func NewBasicCardPayment(amount float64, currency string, label string) PaymentRequest {
|
||||
// return PaymentRequest{
|
||||
// MethodData: []PaymentMethodData{
|
||||
// {
|
||||
// SupportedMethods: MethodCard,
|
||||
// Data: map[string]any{
|
||||
// "supportedNetworks": []string{"visa", "mastercard"},
|
||||
// "supportedTypes": []string{"credit", "debit"},
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Details: PaymentDetails{
|
||||
// Total: PaymentItem{
|
||||
// Label: label,
|
||||
// Amount: Money{
|
||||
// Currency: currency,
|
||||
// Value: formatAmount(amount),
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Options: PaymentOptions{
|
||||
// RequestPayerName: true,
|
||||
// RequestPayerEmail: true,
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Example usage:
|
||||
// func PaymentHandler(c echo.Context) error {
|
||||
// request := NewBasicCardPayment(99.99, "USD", "Product Purchase")
|
||||
//
|
||||
// // Add display items
|
||||
// request.Details.DisplayItems = []PaymentItem{
|
||||
// {
|
||||
// Label: "Product Price",
|
||||
// Amount: Money{
|
||||
// Currency: "USD",
|
||||
// Value: "89.99",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// Label: "Tax",
|
||||
// Amount: Money{
|
||||
// Currency: "USD",
|
||||
// Value: "10.00",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// // Add shipping options
|
||||
// request.Details.ShippingOptions = []ShippingOption{
|
||||
// {
|
||||
// ID: "standard",
|
||||
// Label: "Standard Shipping",
|
||||
// Amount: Money{
|
||||
// Currency: "USD",
|
||||
// Value: "0.00",
|
||||
// },
|
||||
// Selected: true,
|
||||
// },
|
||||
// {
|
||||
// ID: "express",
|
||||
// Label: "Express Shipping",
|
||||
// Amount: Money{
|
||||
// Currency: "USD",
|
||||
// Value: "10.00",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// return InitiatePayment(c, request)
|
||||
// }
|
||||
//
|
||||
// func formatAmount(amount float64) string {
|
||||
// return fmt.Sprintf("%.2f", amount)
|
||||
// }
|
||||
@@ -1,156 +0,0 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"github.com/go-webauthn/webauthn/protocol/webauthncose"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/segmentio/ksuid"
|
||||
|
||||
"github.com/onsonr/sonr/pkg/common"
|
||||
)
|
||||
|
||||
const kWebAuthnTimeout = 6000
|
||||
|
||||
// TODO: Returns fixed chain ID for testing.
|
||||
func GetChainID(c echo.Context) string {
|
||||
return "sonr-testnet-1"
|
||||
}
|
||||
|
||||
// SetVaultAddress sets the address of the vault
|
||||
func SetVaultAddress(c echo.Context, address string) error {
|
||||
return common.WriteCookie(c, common.SonrAddress, address)
|
||||
}
|
||||
|
||||
// SetVaultAuthorization sets the UCAN CID of the vault
|
||||
func SetVaultAuthorization(c echo.Context, ucanCID string) error {
|
||||
common.HeaderWrite(c, common.Authorization, formatAuth(ucanCID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Initialization │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
func loadOrGenKsuid(c echo.Context) error {
|
||||
var (
|
||||
sessionID string
|
||||
err error
|
||||
)
|
||||
|
||||
// Setup genKsuid function
|
||||
genKsuid := func() string {
|
||||
return ksuid.New().String()
|
||||
}
|
||||
|
||||
// Attempt to read the session ID from the "session" cookie
|
||||
if ok := common.CookieExists(c, common.SessionID); !ok {
|
||||
sessionID = genKsuid()
|
||||
} else {
|
||||
sessionID, err = common.ReadCookie(c, common.SessionID)
|
||||
if err != nil {
|
||||
sessionID = genKsuid()
|
||||
}
|
||||
}
|
||||
common.WriteCookie(c, common.SessionID, sessionID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Extraction │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
func extractPeerInfo(c echo.Context) (string, string) {
|
||||
var chal protocol.URLEncodedBase64
|
||||
id, _ := common.ReadCookie(c, common.SessionID)
|
||||
chalRaw, _ := common.ReadCookieBytes(c, common.SessionChallenge)
|
||||
chal.UnmarshalJSON(chalRaw)
|
||||
|
||||
return id, common.Base64Encode(chal)
|
||||
}
|
||||
|
||||
func extractBrowserInfo(c echo.Context) (string, string) {
|
||||
secCHUA := common.HeaderRead(c, common.UserAgent)
|
||||
|
||||
// If common.is empty, return empty BrowserInfo
|
||||
if secCHUA == "" {
|
||||
return "N/A", "-1"
|
||||
}
|
||||
|
||||
// Split the common.into individual browser entries
|
||||
var (
|
||||
name string
|
||||
ver string
|
||||
)
|
||||
entries := strings.Split(strings.TrimSpace(secCHUA), ",")
|
||||
for _, entry := range entries {
|
||||
// Remove leading/trailing spaces and quotes
|
||||
entry = strings.TrimSpace(entry)
|
||||
|
||||
// Use regex to extract the browser name and version
|
||||
re := regexp.MustCompile(`"([^"]+)";v="([^"]+)"`)
|
||||
matches := re.FindStringSubmatch(entry)
|
||||
|
||||
if len(matches) == 3 {
|
||||
browserName := matches[1]
|
||||
version := matches[2]
|
||||
|
||||
// Skip "Not A;Brand"
|
||||
if !validBrowser(browserName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Store the first valid browser info as fallback
|
||||
name = browserName
|
||||
ver = version
|
||||
}
|
||||
}
|
||||
return name, ver
|
||||
}
|
||||
|
||||
func validBrowser(name string) bool {
|
||||
return name != common.BrowserNameUnknown.String() && name != common.BrowserNameChromium.String()
|
||||
}
|
||||
|
||||
// ╭───────────────────────────────────────────────────────────╮
|
||||
// │ Authentication │
|
||||
// ╰───────────────────────────────────────────────────────────╯
|
||||
|
||||
func buildUserEntity(userID string) protocol.UserEntity {
|
||||
return protocol.UserEntity{
|
||||
ID: userID,
|
||||
}
|
||||
}
|
||||
|
||||
// returns the base options for registering a new user without challenge or user entity.
|
||||
func baseRegisterOptions() *protocol.PublicKeyCredentialCreationOptions {
|
||||
return &protocol.PublicKeyCredentialCreationOptions{
|
||||
Timeout: kWebAuthnTimeout,
|
||||
Attestation: protocol.PreferDirectAttestation,
|
||||
AuthenticatorSelection: protocol.AuthenticatorSelection{
|
||||
AuthenticatorAttachment: "platform",
|
||||
ResidentKey: protocol.ResidentKeyRequirementPreferred,
|
||||
UserVerification: "preferred",
|
||||
},
|
||||
Parameters: []protocol.CredentialParameter{
|
||||
{
|
||||
Type: "public-key",
|
||||
Algorithm: webauthncose.AlgES256,
|
||||
},
|
||||
{
|
||||
Type: "public-key",
|
||||
Algorithm: webauthncose.AlgES256K,
|
||||
},
|
||||
{
|
||||
Type: "public-key",
|
||||
Algorithm: webauthncose.AlgEdDSA,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func formatAuth(ucanCID string) string {
|
||||
return "Bearer " + ucanCID
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/onsonr/sonr/app/vault/types"
|
||||
"github.com/onsonr/sonr/pkg/common"
|
||||
)
|
||||
|
||||
type SessionCtx interface {
|
||||
ID() string
|
||||
BrowserName() string
|
||||
BrowserVersion() string
|
||||
}
|
||||
|
||||
type contextKey string
|
||||
|
||||
// Context keys
|
||||
const (
|
||||
DataContextKey contextKey = "http_session_data"
|
||||
)
|
||||
|
||||
// Get returns the session.Context from the echo context.
|
||||
func Get(c echo.Context) (SessionCtx, error) {
|
||||
ctx, ok := c.(*HTTPContext)
|
||||
if !ok {
|
||||
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Session Context not found")
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// WebNodeMiddleware establishes a Session Cookie.
|
||||
func Middleware(config *types.Config) echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
err := injectConfig(c, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cc := injectSession(c, common.RoleMotr)
|
||||
return next(cc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func injectConfig(c echo.Context, config *types.Config) error {
|
||||
common.HeaderWrite(c, common.SonrAPIURL, config.SonrApiUrl)
|
||||
common.HeaderWrite(c, common.SonrRPCURL, config.SonrRpcUrl)
|
||||
|
||||
common.WriteCookie(c, common.SonrAddress, config.MotrAddress)
|
||||
schemaBz, err := json.Marshal(config.VaultSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.WriteCookieBytes(c, common.VaultSchema, schemaBz)
|
||||
return nil
|
||||
}
|
||||
|
||||
// injectSession returns the session injectSession from the cookies.
|
||||
func injectSession(c echo.Context, role common.PeerRole) *HTTPContext {
|
||||
if c == nil {
|
||||
return initHTTPContext(nil)
|
||||
}
|
||||
|
||||
common.WriteCookie(c, common.SessionRole, role.String())
|
||||
|
||||
// Continue even if there are errors, just ensure we have valid session data
|
||||
if err := loadOrGenKsuid(c); err != nil {
|
||||
// Log error but continue
|
||||
}
|
||||
return initHTTPContext(c)
|
||||
}
|
||||
|
||||
// HasAuthorization checks if the request has an authorization header
|
||||
func HasAuthorization(c echo.Context) bool {
|
||||
return common.HeaderExists(c, common.Authorization)
|
||||
}
|
||||
|
||||
// HasUserHandle checks if the request has a user handle cookie
|
||||
func HasUserHandle(c echo.Context) bool {
|
||||
return common.CookieExists(c, common.UserHandle)
|
||||
}
|
||||
|
||||
// HasVaultAddress checks if the request has a vault address cookie
|
||||
func HasVaultAddress(c echo.Context) bool {
|
||||
return common.CookieExists(c, common.SonrAddress)
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package authorize
|
||||
|
||||
type AuthorizeRequest struct {
|
||||
Subject string
|
||||
Action string
|
||||
Origin string
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package authorize
|
||||
|
||||
type AuthorizeRequest struct {
|
||||
Subject string
|
||||
Action string
|
||||
Origin string
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package dash
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
templ ProfileView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Sonr.ID
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
The decentralized identity layer for the web.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ FeedView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Welcome Back!
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
Continue with your existing Sonr.ID.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package dash
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
func ProfileView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func FeedView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Welcome Back!</h1><p class=\"text-lg text-zinc-500\">Continue with your existing Sonr.ID.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Login</button></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,29 +0,0 @@
|
||||
package index
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
templ NoWebauthnErrorView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
No WebAuthn Devices
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
You don't have any WebAuthn devices connected to your computer.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package index
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
func NoWebauthnErrorView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">No WebAuthn Devices</h1><p class=\"text-lg text-zinc-500\">You don't have any WebAuthn devices connected to your computer.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,57 +0,0 @@
|
||||
package index
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
templ InitialView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Sonr.ID
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
The decentralized identity layer for the web.
|
||||
</p>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="pt-3 flex flex-col items-center justify-center h-full">
|
||||
<div hx-get="/register" hx-swap="outerHTML" class="pointer:cursor-pointer btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ ReturningView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Welcome Back!
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
Continue with your existing Sonr.ID.
|
||||
</p>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="pt-3 flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package index
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
func InitialView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</p></div><br><div class=\"pt-3 flex flex-col items-center justify-center h-full\"><div hx-get=\"/register\" hx-swap=\"outerHTML\" class=\"pointer:cursor-pointer btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</div></div></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func ReturningView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Welcome Back!</h1><p class=\"text-lg text-zinc-500\">Continue with your existing Sonr.ID.</p></div><br><div class=\"pt-3 flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Login</button></div></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,43 +0,0 @@
|
||||
package wallet
|
||||
|
||||
// Payment types
|
||||
type PaymentMethodData struct {
|
||||
SupportedMethods string `json:"supportedMethods"`
|
||||
Data map[string]any `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentItem struct {
|
||||
Label string `json:"label"`
|
||||
Amount Money `json:"amount"`
|
||||
}
|
||||
|
||||
type Money struct {
|
||||
Currency string `json:"currency"`
|
||||
Value string `json:"value"` // Decimal as string for precision
|
||||
}
|
||||
|
||||
type PaymentOptions struct {
|
||||
RequestPayerName bool `json:"requestPayerName,omitempty"`
|
||||
RequestPayerEmail bool `json:"requestPayerEmail,omitempty"`
|
||||
RequestPayerPhone bool `json:"requestPayerPhone,omitempty"`
|
||||
RequestShipping bool `json:"requestShipping,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentDetails struct {
|
||||
Total PaymentItem `json:"total"`
|
||||
DisplayItems []PaymentItem `json:"displayItems,omitempty"`
|
||||
ShippingOptions []ShippingOption `json:"shippingOptions,omitempty"`
|
||||
}
|
||||
|
||||
type ShippingOption struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Amount Money `json:"amount"`
|
||||
Selected bool `json:"selected,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentRequest struct {
|
||||
MethodData []PaymentMethodData `json:"methodData"`
|
||||
Details PaymentDetails `json:"details"`
|
||||
Options PaymentOptions `json:"options,omitempty"`
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package wallet
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
templ DepositFundsView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Sonr.ID
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
The decentralized identity layer for the web.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ SwapTokensView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Sonr.ID
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
The decentralized identity layer for the web.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ ConfirmPasscodeView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Sonr.ID
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
The decentralized identity layer for the web.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ TransferTokensView() {
|
||||
@layout.Root("Sonr.ID") {
|
||||
<div class="flex fixed inset-0 z-[99] w-screen h-screen bg-white">
|
||||
<div class="relative flex flex-wrap items-center w-full h-full px-8">
|
||||
<div class="relative w-full max-w-sm mx-auto lg:mb-0">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<h1 class="text-3xl font-bold text-zinc-900 mb-4">
|
||||
Welcome Back!
|
||||
</h1>
|
||||
<p class="text-lg text-zinc-500">
|
||||
Continue with your existing Sonr.ID.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<button class="btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow">
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{ children... }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package wallet
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/onsonr/sonr/pkg/common/styles/layout"
|
||||
|
||||
func DepositFundsView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func SwapTokensView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func ConfirmPasscodeView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Sonr.ID</h1><p class=\"text-lg text-zinc-500\">The decentralized identity layer for the web.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Get Started</button></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func TransferTokensView() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var7 == nil {
|
||||
templ_7745c5c3_Var7 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><div class=\"relative flex flex-wrap items-center w-full h-full px-8\"><div class=\"relative w-full max-w-sm mx-auto lg:mb-0\"><div class=\"flex flex-col items-center justify-center h-full\"><div class=\"flex flex-col items-center justify-center h-full\"><h1 class=\"text-3xl font-bold text-zinc-900 mb-4\">Welcome Back!</h1><p class=\"text-lg text-zinc-500\">Continue with your existing Sonr.ID.</p></div><div class=\"flex flex-col items-center justify-center h-full\"><button class=\"btn btn-sm text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow\">Login</button></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var7.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.Root("Sonr.ID").Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,107 +0,0 @@
|
||||
package wallet
|
||||
|
||||
var paymentsHandle = templ.NewOnceHandle()
|
||||
|
||||
// Base payments script template
|
||||
templ PaymentsScripts() {
|
||||
@paymentsHandle.Once() {
|
||||
<script type="text/javascript">
|
||||
// Check if Payment Request API is supported
|
||||
function isPaymentRequestSupported() {
|
||||
return window.PaymentRequest !== undefined;
|
||||
}
|
||||
|
||||
// Create and show payment request
|
||||
async function showPaymentRequest(request) {
|
||||
try {
|
||||
const paymentMethods = request.methodData;
|
||||
const details = request.details;
|
||||
const options = request.options || {};
|
||||
|
||||
const paymentRequest = new PaymentRequest(
|
||||
paymentMethods,
|
||||
details,
|
||||
options
|
||||
);
|
||||
|
||||
// Handle shipping address changes if shipping is requested
|
||||
if (options.requestShipping) {
|
||||
paymentRequest.addEventListener('shippingaddresschange', event => {
|
||||
event.updateWith(Promise.resolve(details));
|
||||
});
|
||||
}
|
||||
|
||||
// Handle shipping option changes
|
||||
if (details.shippingOptions && details.shippingOptions.length > 0) {
|
||||
paymentRequest.addEventListener('shippingoptionchange', event => {
|
||||
event.updateWith(Promise.resolve(details));
|
||||
});
|
||||
}
|
||||
|
||||
const response = await paymentRequest.show();
|
||||
|
||||
// Create response object
|
||||
const result = {
|
||||
methodName: response.methodName,
|
||||
details: response.details,
|
||||
};
|
||||
|
||||
if (options.requestPayerName) {
|
||||
result.payerName = response.payerName;
|
||||
}
|
||||
if (options.requestPayerEmail) {
|
||||
result.payerEmail = response.payerEmail;
|
||||
}
|
||||
if (options.requestPayerPhone) {
|
||||
result.payerPhone = response.payerPhone;
|
||||
}
|
||||
if (options.requestShipping) {
|
||||
result.shippingAddress = response.shippingAddress;
|
||||
result.shippingOption = response.shippingOption;
|
||||
}
|
||||
|
||||
// Complete the payment
|
||||
await response.complete('success');
|
||||
|
||||
// Dispatch success event
|
||||
window.dispatchEvent(new CustomEvent('paymentComplete', {
|
||||
detail: result
|
||||
}));
|
||||
|
||||
} catch (err) {
|
||||
// Dispatch error event
|
||||
window.dispatchEvent(new CustomEvent('paymentError', {
|
||||
detail: err.message
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Abort payment request
|
||||
function abortPaymentRequest() {
|
||||
if (window.currentPaymentRequest) {
|
||||
window.currentPaymentRequest.abort();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
}
|
||||
|
||||
// StartPayment for initiating payment request
|
||||
templ StartPayment(request PaymentRequest) {
|
||||
@PaymentsScripts()
|
||||
<script>
|
||||
(async () => {
|
||||
try {
|
||||
if (!isPaymentRequestSupported()) {
|
||||
throw new Error("Payment Request API is not supported in this browser");
|
||||
}
|
||||
const request = { templ.JSONString(request) };
|
||||
await showPaymentRequest(request);
|
||||
} catch (err) {
|
||||
window.dispatchEvent(new CustomEvent('paymentError', {
|
||||
detail: err.message
|
||||
}));
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.793
|
||||
package wallet
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
var paymentsHandle = templ.NewOnceHandle()
|
||||
|
||||
// Base payments script template
|
||||
func PaymentsScripts() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script type=\"text/javascript\">\n // Check if Payment Request API is supported\n function isPaymentRequestSupported() {\n return window.PaymentRequest !== undefined;\n }\n\n // Create and show payment request\n async function showPaymentRequest(request) {\n try {\n const paymentMethods = request.methodData;\n const details = request.details;\n const options = request.options || {};\n\n const paymentRequest = new PaymentRequest(\n paymentMethods,\n details,\n options\n );\n\n // Handle shipping address changes if shipping is requested\n if (options.requestShipping) {\n paymentRequest.addEventListener('shippingaddresschange', event => {\n event.updateWith(Promise.resolve(details));\n });\n }\n\n // Handle shipping option changes\n if (details.shippingOptions && details.shippingOptions.length > 0) {\n paymentRequest.addEventListener('shippingoptionchange', event => {\n event.updateWith(Promise.resolve(details));\n });\n }\n\n const response = await paymentRequest.show();\n \n // Create response object\n const result = {\n methodName: response.methodName,\n details: response.details,\n };\n\n if (options.requestPayerName) {\n result.payerName = response.payerName;\n }\n if (options.requestPayerEmail) {\n result.payerEmail = response.payerEmail;\n }\n if (options.requestPayerPhone) {\n result.payerPhone = response.payerPhone;\n }\n if (options.requestShipping) {\n result.shippingAddress = response.shippingAddress;\n result.shippingOption = response.shippingOption;\n }\n\n // Complete the payment\n await response.complete('success');\n\n // Dispatch success event\n window.dispatchEvent(new CustomEvent('paymentComplete', {\n detail: result\n }));\n\n } catch (err) {\n // Dispatch error event\n window.dispatchEvent(new CustomEvent('paymentError', {\n detail: err.message\n }));\n }\n }\n\n // Abort payment request\n function abortPaymentRequest() {\n if (window.currentPaymentRequest) {\n window.currentPaymentRequest.abort();\n }\n }\n </script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = paymentsHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
// StartPayment for initiating payment request
|
||||
func StartPayment(request PaymentRequest) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = PaymentsScripts().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n (async () => {\n try {\n if (!isPaymentRequestSupported()) {\n throw new Error(\"Payment Request API is not supported in this browser\");\n }\n const request = { templ.JSONString(request) };\n await showPaymentRequest(request);\n } catch (err) {\n window.dispatchEvent(new CustomEvent('paymentError', {\n detail: err.message\n }));\n }\n })();\n </script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -1,51 +0,0 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/onsonr/sonr/pkg/common"
|
||||
)
|
||||
|
||||
// HTTPContext is the context for HTTP endpoints.
|
||||
type HTTPContext struct {
|
||||
echo.Context
|
||||
role common.PeerRole
|
||||
id string
|
||||
chal string
|
||||
bn string
|
||||
bv string
|
||||
}
|
||||
|
||||
// initHTTPContext loads the headers from the request.
|
||||
func initHTTPContext(c echo.Context) *HTTPContext {
|
||||
if c == nil {
|
||||
return &HTTPContext{}
|
||||
}
|
||||
|
||||
id, chal := extractPeerInfo(c)
|
||||
bn, bv := extractBrowserInfo(c)
|
||||
|
||||
cc := &HTTPContext{
|
||||
Context: c,
|
||||
role: common.PeerRole(common.ReadCookieUnsafe(c, common.SessionRole)),
|
||||
id: id,
|
||||
chal: chal,
|
||||
bn: bn,
|
||||
bv: bv,
|
||||
}
|
||||
|
||||
// Set the session data in both contexts
|
||||
return cc
|
||||
}
|
||||
|
||||
func (s *HTTPContext) ID() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *HTTPContext) BrowserName() string {
|
||||
return s.bn
|
||||
}
|
||||
|
||||
func (s *HTTPContext) BrowserVersion() string {
|
||||
return s.bv
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
// Package vault provides the routes for the Decentralized Web Node (...or Sonr Motr).
|
||||
package vault
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/onsonr/sonr/app/vault/handlers"
|
||||
session "github.com/onsonr/sonr/app/vault/internal"
|
||||
"github.com/onsonr/sonr/app/vault/types"
|
||||
)
|
||||
|
||||
// RegisterRoutes registers the Decentralized Web Node API routes.
|
||||
func RegisterRoutes(e *echo.Echo, config *types.Config) {
|
||||
e.Use(session.Middleware(config))
|
||||
|
||||
e.GET("/register/:subject/start", handlers.RegisterSubjectStart)
|
||||
e.POST("/register/:subject/finish", handlers.RegisterSubjectFinish)
|
||||
|
||||
e.GET("/login/:subject/start", handlers.LoginSubjectStart)
|
||||
e.POST("/login/:subject/finish", handlers.LoginSubjectFinish)
|
||||
|
||||
e.GET("/authz/jwks", handlers.GetJWKS)
|
||||
e.GET("/authz/token", handlers.GetToken)
|
||||
e.POST("/:origin/grant/:subject", handlers.GrantAuthorization)
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.motr.DWN`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type Config struct {
|
||||
IpfsGatewayUrl string `pkl:"ipfsGatewayUrl" json:"ipfsGatewayUrl,omitempty"`
|
||||
|
||||
MotrToken string `pkl:"motrToken" json:"motrToken,omitempty"`
|
||||
|
||||
MotrAddress string `pkl:"motrAddress" json:"motrAddress,omitempty"`
|
||||
|
||||
SonrApiUrl string `pkl:"sonrApiUrl" json:"sonrApiUrl,omitempty"`
|
||||
|
||||
SonrRpcUrl string `pkl:"sonrRpcUrl" json:"sonrRpcUrl,omitempty"`
|
||||
|
||||
SonrChainId string `pkl:"sonrChainId" json:"sonrChainId,omitempty"`
|
||||
|
||||
VaultSchema *Schema `pkl:"vaultSchema" json:"vaultSchema,omitempty"`
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.motr.DWN`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/apple/pkl-go/pkl"
|
||||
)
|
||||
|
||||
type DWN struct {
|
||||
}
|
||||
|
||||
// LoadFromPath loads the pkl module at the given path and evaluates it into a DWN
|
||||
func LoadFromPath(ctx context.Context, path string) (ret *DWN, err error) {
|
||||
evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
cerr := evaluator.Close()
|
||||
if err == nil {
|
||||
err = cerr
|
||||
}
|
||||
}()
|
||||
ret, err = Load(ctx, evaluator, pkl.FileSource(path))
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Load loads the pkl module at the given source and evaluates it with the given evaluator into a DWN
|
||||
func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*DWN, error) {
|
||||
var ret DWN
|
||||
if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ret, nil
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.motr.DWN`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type Environment struct {
|
||||
IsDevelopment bool `pkl:"isDevelopment" json:"isDevelopment,omitempty"`
|
||||
|
||||
CacheVersion string `pkl:"cacheVersion" json:"cacheVersion,omitempty"`
|
||||
|
||||
HttpserverPath string `pkl:"httpserverPath" json:"httpserverPath,omitempty"`
|
||||
|
||||
WasmExecPath string `pkl:"wasmExecPath" json:"wasmExecPath,omitempty"`
|
||||
|
||||
WasmPath string `pkl:"wasmPath" json:"wasmPath,omitempty"`
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.motr.DWN`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type Schema struct {
|
||||
Version int `pkl:"version"`
|
||||
|
||||
Account string `pkl:"account" json:"account,omitempty"`
|
||||
|
||||
Asset string `pkl:"asset" json:"asset,omitempty"`
|
||||
|
||||
Chain string `pkl:"chain" json:"chain,omitempty"`
|
||||
|
||||
Credential string `pkl:"credential" json:"credential,omitempty"`
|
||||
|
||||
Jwk string `pkl:"jwk" json:"jwk,omitempty"`
|
||||
|
||||
Grant string `pkl:"grant" json:"grant,omitempty"`
|
||||
|
||||
Keyshare string `pkl:"keyshare" json:"keyshare,omitempty"`
|
||||
|
||||
Profile string `pkl:"profile" json:"profile,omitempty"`
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Code generated from Pkl module `sonr.motr.DWN`. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
import "github.com/apple/pkl-go/pkl"
|
||||
|
||||
func init() {
|
||||
pkl.RegisterMapping("sonr.motr.DWN", DWN{})
|
||||
pkl.RegisterMapping("sonr.motr.DWN#Config", Config{})
|
||||
pkl.RegisterMapping("sonr.motr.DWN#Schema", Schema{})
|
||||
pkl.RegisterMapping("sonr.motr.DWN#Environment", Environment{})
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package vault
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func WasmContextMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// Extract WASM context from headers
|
||||
if wasmCtx := c.Request().Header.Get("X-Wasm-Context"); wasmCtx != "" {
|
||||
if ctx, err := DecodeWasmContext(wasmCtx); err == nil {
|
||||
c.Set("wasm_context", ctx)
|
||||
}
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
||||
// decodeWasmContext decodes the WASM context from a base64 encoded string
|
||||
func DecodeWasmContext(ctx string) (map[string]any, error) {
|
||||
decoded, err := base64.StdEncoding.DecodeString(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ctxData map[string]any
|
||||
err = json.Unmarshal(decoded, &ctxData)
|
||||
return ctxData, err
|
||||
}
|
||||
Reference in New Issue
Block a user