diff --git a/clavis/clavis-cli/.clangd b/clavis/clavis-cli/.clangd new file mode 100644 index 0000000..2c2ffe2 --- /dev/null +++ b/clavis/clavis-cli/.clangd @@ -0,0 +1,68 @@ +# clangd configuration for clavitor-cli +# Place this at project root + +CompileFlags: + # Base C11 standard + Add: + - -std=c11 + - -Wall + - -Wextra + - -DNDEBUG + - -D_GNU_SOURCE + # Include paths + - -Ivendor/bearssl/inc + - -Ivendor/bearssl/src + - -Ivendor/quickjs + - -Ivendor/cjson + - -Isrc + # QuickJS specific defines + - -DCONFIG_VERSION=\"2025-04-26\" + - -DCONFIG_BIGNUM + +--- +# Different settings for QuickJS source files (uses gnu11) +If: + PathMatch: vendor/quickjs/.* +CompileFlags: + Add: + - -std=gnu11 + - -DCONFIG_VERSION=\"2025-04-26\" + - -DCONFIG_BIGNUM + - -D_GNU_SOURCE + - -Ivendor/quickjs + Remove: + - -std=c11 + +--- +# BearSSL source files +If: + PathMatch: vendor/bearssl/.* +CompileFlags: + Add: + - -Ivendor/bearssl/inc + - -Ivendor/bearssl/src + +--- +# cJSON source files +If: + PathMatch: vendor/cjson/.* +CompileFlags: + Add: + - -Ivendor/cjson + +Index: + # Enable background indexing + Background: Build + +Diagnostics: + # Show all diagnostics + UnusedIncludes: Strict + MissingIncludes: Strict + +Completion: + # Include all completion results + AllScopes: true + +Hover: + # Show more info in hover + ShowAKA: true diff --git a/clavis/clavis-cli/.opencode/init b/clavis/clavis-cli/.opencode/init new file mode 100644 index 0000000..e69de29 diff --git a/clavis/clavis-cli/.opencode/opencode.db b/clavis/clavis-cli/.opencode/opencode.db new file mode 100644 index 0000000..c4b4835 Binary files /dev/null and b/clavis/clavis-cli/.opencode/opencode.db differ diff --git a/clavitor.com/account/account.db b/clavis/clavis-cli/.opencode/opencode.db-shm similarity index 80% rename from clavitor.com/account/account.db rename to clavis/clavis-cli/.opencode/opencode.db-shm index 2b20838..22d6c2b 100644 Binary files a/clavitor.com/account/account.db and b/clavis/clavis-cli/.opencode/opencode.db-shm differ diff --git a/clavis/clavis-cli/.opencode/opencode.db-wal b/clavis/clavis-cli/.opencode/opencode.db-wal new file mode 100644 index 0000000..76e50b8 Binary files /dev/null and b/clavis/clavis-cli/.opencode/opencode.db-wal differ diff --git a/clavis/clavis-cli/OpenCode.md b/clavis/clavis-cli/OpenCode.md new file mode 100644 index 0000000..0f68ec4 --- /dev/null +++ b/clavis/clavis-cli/OpenCode.md @@ -0,0 +1,33 @@ +# clavitor-cli — Pure C CLI for credential access + +## Build +```bash +make # build for host (output: clavitor-cli) +make strip # strip binary (<1MB target) +make clean # remove build artifacts +make size # show binary size +``` + +## Test +```bash +./clavitor-cli test-crypto # BearSSL + JS crypto self-tests +./clavitor-cli test-totp # TOTP generation test +./clavitor-cli test-roundtrip # runs crypto/test_crypto.js +``` + +## Code Style +- **Standard**: C11 (`-std=c11`), QuickJS sources use `-std=gnu11` +- **Indent**: 4 spaces +- **Comments**: `/* */` style only +- **Naming**: `snake_case` functions, `struct clv_*` types, `CLV_*_H` include guards +- **Headers**: Include guards required, co-located with .c files in `src/` +- **Error handling**: Return 0 for success, non-zero for failure +- **Static**: Mark internal functions as `static` +- **No system deps**: All dependencies vendored in `vendor/` + +## Architecture +- `src/main.c` — CLI entry, command parsing (get, list, totp, test-*) +- `src/http.c` — HTTPS client via BearSSL +- `src/keystore.c` — AES-GCM encrypted config at `~/.config/clavitor/config` +- `src/jsbridge.c` — QuickJS bridge for shared crypto logic +- `src/util.c` — Base64, URL encoding diff --git a/clavis/clavis-cli/build/src/http.o b/clavis/clavis-cli/build/src/http.o new file mode 100644 index 0000000..146ec03 Binary files /dev/null and b/clavis/clavis-cli/build/src/http.o differ diff --git a/clavis/clavis-cli/build/src/jsbridge.o b/clavis/clavis-cli/build/src/jsbridge.o new file mode 100644 index 0000000..29d672d Binary files /dev/null and b/clavis/clavis-cli/build/src/jsbridge.o differ diff --git a/clavis/clavis-cli/build/src/keystore.o b/clavis/clavis-cli/build/src/keystore.o new file mode 100644 index 0000000..cf2661a Binary files /dev/null and b/clavis/clavis-cli/build/src/keystore.o differ diff --git a/clavis/clavis-cli/build/src/main.o b/clavis/clavis-cli/build/src/main.o new file mode 100644 index 0000000..1f339fa Binary files /dev/null and b/clavis/clavis-cli/build/src/main.o differ diff --git a/clavis/clavis-cli/build/src/util.o b/clavis/clavis-cli/build/src/util.o new file mode 100644 index 0000000..58417a1 Binary files /dev/null and b/clavis/clavis-cli/build/src/util.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/aead/ccm.o b/clavis/clavis-cli/build/vendor/bearssl/src/aead/ccm.o new file mode 100644 index 0000000..0cd52ec Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/aead/ccm.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/aead/eax.o b/clavis/clavis-cli/build/vendor/bearssl/src/aead/eax.o new file mode 100644 index 0000000..6b6739f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/aead/eax.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/aead/gcm.o b/clavis/clavis-cli/build/vendor/bearssl/src/aead/gcm.o new file mode 100644 index 0000000..2e028b1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/aead/gcm.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/ccopy.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/ccopy.o new file mode 100644 index 0000000..aa018e1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/ccopy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec16be.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec16be.o new file mode 100644 index 0000000..dafdfb4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec16be.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec16le.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec16le.o new file mode 100644 index 0000000..924871e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec16le.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec32be.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec32be.o new file mode 100644 index 0000000..ce6b416 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec32be.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec32le.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec32le.o new file mode 100644 index 0000000..2c6b747 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec32le.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec64be.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec64be.o new file mode 100644 index 0000000..647d23c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec64be.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec64le.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec64le.o new file mode 100644 index 0000000..6d09a29 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/dec64le.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc16be.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc16be.o new file mode 100644 index 0000000..dab9811 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc16be.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc16le.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc16le.o new file mode 100644 index 0000000..4d9709a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc16le.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc32be.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc32be.o new file mode 100644 index 0000000..0988fce Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc32be.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc32le.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc32le.o new file mode 100644 index 0000000..08a43b6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc32le.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc64be.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc64be.o new file mode 100644 index 0000000..92f92a3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc64be.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc64le.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc64le.o new file mode 100644 index 0000000..de4cdf2 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/enc64le.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/pemdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/pemdec.o new file mode 100644 index 0000000..2ed8373 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/pemdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/codec/pemenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/codec/pemenc.o new file mode 100644 index 0000000..37cd731 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/codec/pemenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_all_m15.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_all_m15.o new file mode 100644 index 0000000..29860fc Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_all_m15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_all_m31.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_all_m31.o new file mode 100644 index 0000000..f2a5fb1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_all_m31.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_i15.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_i15.o new file mode 100644 index 0000000..8d9f1b0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_i15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_i31.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_i31.o new file mode 100644 index 0000000..d23df24 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_i31.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m15.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m15.o new file mode 100644 index 0000000..0ba2e89 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m31.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m31.o new file mode 100644 index 0000000..aef418c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m31.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m62.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m62.o new file mode 100644 index 0000000..a1da8aa Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m62.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m64.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m64.o new file mode 100644 index 0000000..fea9c46 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_c25519_m64.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_curve25519.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_curve25519.o new file mode 100644 index 0000000..f754d9b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_curve25519.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_default.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_default.o new file mode 100644 index 0000000..1edcfc1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_default.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_keygen.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_keygen.o new file mode 100644 index 0000000..2f9a7db Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_keygen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m15.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m15.o new file mode 100644 index 0000000..22843e0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m31.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m31.o new file mode 100644 index 0000000..e3515a3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m31.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m62.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m62.o new file mode 100644 index 0000000..437d339 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m62.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m64.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m64.o new file mode 100644 index 0000000..01907f0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_p256_m64.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_prime_i15.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_prime_i15.o new file mode 100644 index 0000000..b31551f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_prime_i15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_prime_i31.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_prime_i31.o new file mode 100644 index 0000000..c6fd344 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_prime_i31.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_pubkey.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_pubkey.o new file mode 100644 index 0000000..6c7f5e5 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_pubkey.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp256r1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp256r1.o new file mode 100644 index 0000000..dc546bf Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp256r1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp384r1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp384r1.o new file mode 100644 index 0000000..9a88005 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp384r1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp521r1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp521r1.o new file mode 100644 index 0000000..17f3f65 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ec_secp521r1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_atr.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_atr.o new file mode 100644 index 0000000..6daca69 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_atr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_asn1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_asn1.o new file mode 100644 index 0000000..3ee438f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_asn1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_raw.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_raw.o new file mode 100644 index 0000000..66f82f7 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_raw.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_asn1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_asn1.o new file mode 100644 index 0000000..26f5b6d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_asn1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_raw.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_raw.o new file mode 100644 index 0000000..ac64483 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_raw.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_bits.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_bits.o new file mode 100644 index 0000000..398808f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_bits.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_asn1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_asn1.o new file mode 100644 index 0000000..11197e7 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_asn1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_raw.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_raw.o new file mode 100644 index 0000000..a69f0e3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_raw.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_asn1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_asn1.o new file mode 100644 index 0000000..88d8b57 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_asn1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_raw.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_raw.o new file mode 100644 index 0000000..d6e32a4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_raw.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_bits.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_bits.o new file mode 100644 index 0000000..4a82b6e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_bits.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_asn1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_asn1.o new file mode 100644 index 0000000..064f657 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_asn1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_raw.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_raw.o new file mode 100644 index 0000000..6e22215 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_raw.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_asn1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_asn1.o new file mode 100644 index 0000000..1dec57a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_asn1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_raw.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_raw.o new file mode 100644 index 0000000..a153667 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_raw.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_rta.o b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_rta.o new file mode 100644 index 0000000..fe13b67 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ec/ecdsa_rta.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/dig_oid.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/dig_oid.o new file mode 100644 index 0000000..af48f12 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/dig_oid.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/dig_size.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/dig_size.o new file mode 100644 index 0000000..91102e3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/dig_size.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul.o new file mode 100644 index 0000000..e9eb5b3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul32.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul32.o new file mode 100644 index 0000000..f4ec1ed Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul32.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul64.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul64.o new file mode 100644 index 0000000..09d0250 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_ctmul64.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_pclmul.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_pclmul.o new file mode 100644 index 0000000..cf5bac4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_pclmul.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_pwr8.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_pwr8.o new file mode 100644 index 0000000..e76f6c1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/ghash_pwr8.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/md5.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/md5.o new file mode 100644 index 0000000..7e2696d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/md5.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/md5sha1.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/md5sha1.o new file mode 100644 index 0000000..7ab8f5c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/md5sha1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/mgf1.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/mgf1.o new file mode 100644 index 0000000..96dda2e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/mgf1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/multihash.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/multihash.o new file mode 100644 index 0000000..82695d1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/multihash.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha1.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha1.o new file mode 100644 index 0000000..34474ed Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha2big.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha2big.o new file mode 100644 index 0000000..ff68d73 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha2big.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha2small.o b/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha2small.o new file mode 100644 index 0000000..8161a01 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/hash/sha2small.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_add.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_add.o new file mode 100644 index 0000000..8a2702f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_add.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_bitlen.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_bitlen.o new file mode 100644 index 0000000..542ba88 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_bitlen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decmod.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decmod.o new file mode 100644 index 0000000..b7e1204 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decmod.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decode.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decode.o new file mode 100644 index 0000000..e4a6b10 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decode.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decred.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decred.o new file mode 100644 index 0000000..86044b9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_decred.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_encode.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_encode.o new file mode 100644 index 0000000..82e92f0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_encode.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_fmont.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_fmont.o new file mode 100644 index 0000000..1c5587c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_fmont.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_iszero.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_iszero.o new file mode 100644 index 0000000..474ba5f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_iszero.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_moddiv.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_moddiv.o new file mode 100644 index 0000000..36cd364 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_moddiv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_modpow.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_modpow.o new file mode 100644 index 0000000..fd0cd24 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_modpow.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_modpow2.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_modpow2.o new file mode 100644 index 0000000..52d49c8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_modpow2.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_montmul.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_montmul.o new file mode 100644 index 0000000..5fdfc0a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_montmul.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_mulacc.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_mulacc.o new file mode 100644 index 0000000..229c2cb Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_mulacc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_muladd.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_muladd.o new file mode 100644 index 0000000..11a59a1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_muladd.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_ninv15.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_ninv15.o new file mode 100644 index 0000000..d8be40f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_ninv15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_reduce.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_reduce.o new file mode 100644 index 0000000..967d868 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_reduce.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_rshift.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_rshift.o new file mode 100644 index 0000000..16e5047 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_rshift.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_sub.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_sub.o new file mode 100644 index 0000000..a47c2fb Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_sub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_tmont.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_tmont.o new file mode 100644 index 0000000..4a31d11 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i15_tmont.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_add.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_add.o new file mode 100644 index 0000000..0f597b5 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_add.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_bitlen.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_bitlen.o new file mode 100644 index 0000000..a786e41 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_bitlen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decmod.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decmod.o new file mode 100644 index 0000000..4a53d47 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decmod.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decode.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decode.o new file mode 100644 index 0000000..f9f4168 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decode.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decred.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decred.o new file mode 100644 index 0000000..0e72700 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_decred.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_encode.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_encode.o new file mode 100644 index 0000000..d9e6730 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_encode.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_fmont.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_fmont.o new file mode 100644 index 0000000..549de3c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_fmont.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_iszero.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_iszero.o new file mode 100644 index 0000000..680171c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_iszero.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_moddiv.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_moddiv.o new file mode 100644 index 0000000..837718d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_moddiv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_modpow.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_modpow.o new file mode 100644 index 0000000..9c60a5c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_modpow.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_modpow2.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_modpow2.o new file mode 100644 index 0000000..f25f2c6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_modpow2.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_montmul.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_montmul.o new file mode 100644 index 0000000..2fdbbe1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_montmul.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_mulacc.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_mulacc.o new file mode 100644 index 0000000..a3221d6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_mulacc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_muladd.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_muladd.o new file mode 100644 index 0000000..b78700e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_muladd.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_ninv31.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_ninv31.o new file mode 100644 index 0000000..6f0f97f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_ninv31.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_reduce.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_reduce.o new file mode 100644 index 0000000..0dafc7e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_reduce.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_rshift.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_rshift.o new file mode 100644 index 0000000..d61475b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_rshift.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_sub.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_sub.o new file mode 100644 index 0000000..7cdcbf1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_sub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_tmont.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_tmont.o new file mode 100644 index 0000000..36d4fc5 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i31_tmont.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_add.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_add.o new file mode 100644 index 0000000..23f8635 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_add.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_bitlen.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_bitlen.o new file mode 100644 index 0000000..aa69b7d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_bitlen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decmod.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decmod.o new file mode 100644 index 0000000..e3a5d3c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decmod.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decode.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decode.o new file mode 100644 index 0000000..9f7d3d0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decode.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decred.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decred.o new file mode 100644 index 0000000..9901467 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_decred.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_div32.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_div32.o new file mode 100644 index 0000000..6956f84 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_div32.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_encode.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_encode.o new file mode 100644 index 0000000..b2efe2a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_encode.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_fmont.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_fmont.o new file mode 100644 index 0000000..a065f40 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_fmont.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_iszero.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_iszero.o new file mode 100644 index 0000000..34e51ba Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_iszero.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_modpow.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_modpow.o new file mode 100644 index 0000000..acbe4f9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_modpow.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_montmul.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_montmul.o new file mode 100644 index 0000000..1eb4bc7 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_montmul.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_mulacc.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_mulacc.o new file mode 100644 index 0000000..0881831 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_mulacc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_muladd.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_muladd.o new file mode 100644 index 0000000..f7ca2cf Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_muladd.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_ninv32.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_ninv32.o new file mode 100644 index 0000000..8a130a7 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_ninv32.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_reduce.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_reduce.o new file mode 100644 index 0000000..c652c68 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_reduce.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_sub.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_sub.o new file mode 100644 index 0000000..aea7095 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_sub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_tmont.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_tmont.o new file mode 100644 index 0000000..76a17b9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i32_tmont.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/int/i62_modpow2.o b/clavis/clavis-cli/build/vendor/bearssl/src/int/i62_modpow2.o new file mode 100644 index 0000000..1691162 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/int/i62_modpow2.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/kdf/hkdf.o b/clavis/clavis-cli/build/vendor/bearssl/src/kdf/hkdf.o new file mode 100644 index 0000000..b0601e1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/kdf/hkdf.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/kdf/shake.o b/clavis/clavis-cli/build/vendor/bearssl/src/kdf/shake.o new file mode 100644 index 0000000..cf7b2c9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/kdf/shake.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/mac/hmac.o b/clavis/clavis-cli/build/vendor/bearssl/src/mac/hmac.o new file mode 100644 index 0000000..30f6c3e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/mac/hmac.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/mac/hmac_ct.o b/clavis/clavis-cli/build/vendor/bearssl/src/mac/hmac_ct.o new file mode 100644 index 0000000..8f97c89 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/mac/hmac_ct.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rand/aesctr_drbg.o b/clavis/clavis-cli/build/vendor/bearssl/src/rand/aesctr_drbg.o new file mode 100644 index 0000000..fe7243a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rand/aesctr_drbg.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rand/hmac_drbg.o b/clavis/clavis-cli/build/vendor/bearssl/src/rand/hmac_drbg.o new file mode 100644 index 0000000..301a876 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rand/hmac_drbg.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rand/sysrng.o b/clavis/clavis-cli/build/vendor/bearssl/src/rand/sysrng.o new file mode 100644 index 0000000..831098c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rand/sysrng.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_keygen.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_keygen.o new file mode 100644 index 0000000..c0eb810 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_keygen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_modulus.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_modulus.o new file mode 100644 index 0000000..91373c4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_modulus.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_decrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_decrypt.o new file mode 100644 index 0000000..bccb30b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_decrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_encrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_encrypt.o new file mode 100644 index 0000000..66c08f6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_encrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_sign.o new file mode 100644 index 0000000..fe4bb3b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_vrfy.o new file mode 100644 index 0000000..71c7367 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_priv.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_priv.o new file mode 100644 index 0000000..706dd4d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_priv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_privexp.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_privexp.o new file mode 100644 index 0000000..a182640 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_privexp.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pss_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pss_sign.o new file mode 100644 index 0000000..4fe3f68 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pss_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pss_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pss_vrfy.o new file mode 100644 index 0000000..668487c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pss_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pub.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pub.o new file mode 100644 index 0000000..894509c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pubexp.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pubexp.o new file mode 100644 index 0000000..c095702 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_default_pubexp.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_keygen.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_keygen.o new file mode 100644 index 0000000..fb1b15a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_keygen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_modulus.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_modulus.o new file mode 100644 index 0000000..def8c4c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_modulus.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_decrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_decrypt.o new file mode 100644 index 0000000..6885915 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_decrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_encrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_encrypt.o new file mode 100644 index 0000000..039d16f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_encrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_sign.o new file mode 100644 index 0000000..f45cc78 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.o new file mode 100644 index 0000000..c66e10f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_priv.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_priv.o new file mode 100644 index 0000000..5e14774 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_priv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_privexp.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_privexp.o new file mode 100644 index 0000000..9e54404 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_privexp.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_sign.o new file mode 100644 index 0000000..5bcf8f1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_vrfy.o new file mode 100644 index 0000000..a7740a8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pub.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pub.o new file mode 100644 index 0000000..c9d68bb Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pubexp.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pubexp.o new file mode 100644 index 0000000..31f80d4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i15_pubexp.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen.o new file mode 100644 index 0000000..14cccd8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen_inner.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen_inner.o new file mode 100644 index 0000000..e981666 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen_inner.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_modulus.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_modulus.o new file mode 100644 index 0000000..2c71d63 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_modulus.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_decrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_decrypt.o new file mode 100644 index 0000000..53eb495 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_decrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_encrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_encrypt.o new file mode 100644 index 0000000..e11ac7d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_encrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_sign.o new file mode 100644 index 0000000..155091a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.o new file mode 100644 index 0000000..84eaefe Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_priv.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_priv.o new file mode 100644 index 0000000..6fadd84 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_priv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_privexp.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_privexp.o new file mode 100644 index 0000000..38bf5bd Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_privexp.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_sign.o new file mode 100644 index 0000000..0b137f6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_vrfy.o new file mode 100644 index 0000000..63b17d3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pub.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pub.o new file mode 100644 index 0000000..e92d6cb Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pubexp.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pubexp.o new file mode 100644 index 0000000..403ec4f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i31_pubexp.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_decrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_decrypt.o new file mode 100644 index 0000000..bdb6881 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_decrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_encrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_encrypt.o new file mode 100644 index 0000000..554537f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_encrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_sign.o new file mode 100644 index 0000000..f9b9b7d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.o new file mode 100644 index 0000000..0cdaeab Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_priv.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_priv.o new file mode 100644 index 0000000..991422a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_priv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_sign.o new file mode 100644 index 0000000..3b5a96a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_vrfy.o new file mode 100644 index 0000000..9a46da0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pub.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pub.o new file mode 100644 index 0000000..8b4be3b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i32_pub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_keygen.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_keygen.o new file mode 100644 index 0000000..9e0cb61 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_keygen.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_decrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_decrypt.o new file mode 100644 index 0000000..e1d48e3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_decrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_encrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_encrypt.o new file mode 100644 index 0000000..b35c68c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_encrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_sign.o new file mode 100644 index 0000000..290d468 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.o new file mode 100644 index 0000000..6324b56 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_priv.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_priv.o new file mode 100644 index 0000000..c9b62dd Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_priv.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_sign.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_sign.o new file mode 100644 index 0000000..87ee5b3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_sign.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_vrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_vrfy.o new file mode 100644 index 0000000..988752a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_vrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pub.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pub.o new file mode 100644 index 0000000..02d0485 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_i62_pub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_oaep_pad.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_oaep_pad.o new file mode 100644 index 0000000..17022f3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_oaep_pad.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_oaep_unpad.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_oaep_unpad.o new file mode 100644 index 0000000..ce19d65 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_oaep_unpad.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_pad.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_pad.o new file mode 100644 index 0000000..c216eac Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_pad.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_unpad.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_unpad.o new file mode 100644 index 0000000..a9198c8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_unpad.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_pad.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_pad.o new file mode 100644 index 0000000..95089c5 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_pad.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_unpad.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_unpad.o new file mode 100644 index 0000000..01b9de2 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_unpad.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_ssl_decrypt.o b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_ssl_decrypt.o new file mode 100644 index 0000000..c05128f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/rsa/rsa_ssl_decrypt.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/settings.o b/clavis/clavis-cli/build/vendor/bearssl/src/settings.o new file mode 100644 index 0000000..99b7833 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/settings.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf.o new file mode 100644 index 0000000..eecd342 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_md5sha1.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_md5sha1.o new file mode 100644 index 0000000..b6972a3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_md5sha1.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_sha256.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_sha256.o new file mode 100644 index 0000000..7ea4acb Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_sha256.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_sha384.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_sha384.o new file mode 100644 index 0000000..e61581d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/prf_sha384.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_ec.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_ec.o new file mode 100644 index 0000000..fc00ab5 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_ec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_rsa.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_rsa.o new file mode 100644 index 0000000..1ca024f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_rsa.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client.o new file mode 100644 index 0000000..c9542fe Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client_default_rsapub.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client_default_rsapub.o new file mode 100644 index 0000000..0ef21f9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client_default_rsapub.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client_full.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client_full.o new file mode 100644 index 0000000..90f3bb9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_client_full.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine.o new file mode 100644 index 0000000..5770fa9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aescbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aescbc.o new file mode 100644 index 0000000..0c965c6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aescbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesccm.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesccm.o new file mode 100644 index 0000000..e5f2a68 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesccm.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesgcm.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesgcm.o new file mode 100644 index 0000000..150e2d0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesgcm.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_chapol.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_chapol.o new file mode 100644 index 0000000..3b02352 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_chapol.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_descbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_descbc.o new file mode 100644 index 0000000..a66301b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_descbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ec.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ec.o new file mode 100644 index 0000000..fc2a5df Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ecdsa.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ecdsa.o new file mode 100644 index 0000000..a478c16 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ecdsa.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_rsavrfy.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_rsavrfy.o new file mode 100644 index 0000000..f1ead26 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_engine_default_rsavrfy.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hashes.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hashes.o new file mode 100644 index 0000000..d878c1f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hashes.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hs_client.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hs_client.o new file mode 100644 index 0000000..c9a1946 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hs_client.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hs_server.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hs_server.o new file mode 100644 index 0000000..8b9f710 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_hs_server.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_io.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_io.o new file mode 100644 index 0000000..f215faa Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_io.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_keyexport.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_keyexport.o new file mode 100644 index 0000000..2e9696f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_keyexport.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_lru.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_lru.o new file mode 100644 index 0000000..7542c1d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_lru.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_cbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_cbc.o new file mode 100644 index 0000000..f5c76c4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_cbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_ccm.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_ccm.o new file mode 100644 index 0000000..77a50eb Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_ccm.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_chapol.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_chapol.o new file mode 100644 index 0000000..5b47779 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_chapol.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_gcm.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_gcm.o new file mode 100644 index 0000000..d63eeb5 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_rec_gcm.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_scert_single_ec.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_scert_single_ec.o new file mode 100644 index 0000000..c8f194f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_scert_single_ec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_scert_single_rsa.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_scert_single_rsa.o new file mode 100644 index 0000000..3422d7f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_scert_single_rsa.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server.o new file mode 100644 index 0000000..29fbda1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_full_ec.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_full_ec.o new file mode 100644 index 0000000..2ac9b49 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_full_ec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_full_rsa.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_full_rsa.o new file mode 100644 index 0000000..c6cc34c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_full_rsa.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_mine2c.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_mine2c.o new file mode 100644 index 0000000..43a2d81 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_mine2c.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_mine2g.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_mine2g.o new file mode 100644 index 0000000..a63d724 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_mine2g.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minf2c.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minf2c.o new file mode 100644 index 0000000..217a778 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minf2c.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minf2g.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minf2g.o new file mode 100644 index 0000000..3ebd60d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minf2g.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minr2g.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minr2g.o new file mode 100644 index 0000000..7aff9a8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minr2g.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minu2g.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minu2g.o new file mode 100644 index 0000000..d0f81ad Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minu2g.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minv2g.o b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minv2g.o new file mode 100644 index 0000000..30897b9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/ssl/ssl_server_minv2g.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_cbcdec.o new file mode 100644 index 0000000..7bfd706 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_cbcenc.o new file mode 100644 index 0000000..7802add Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_ctr.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_ctr.o new file mode 100644 index 0000000..0eba1ce Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_ctr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_ctrcbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_ctrcbc.o new file mode 100644 index 0000000..45cc5d2 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_ctrcbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_dec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_dec.o new file mode 100644 index 0000000..8a0c7a1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_dec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_enc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_enc.o new file mode 100644 index 0000000..9e08b20 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_big_enc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_common.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_common.o new file mode 100644 index 0000000..fb02958 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_common.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct.o new file mode 100644 index 0000000..7470d68 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64.o new file mode 100644 index 0000000..e4ee9a3 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcdec.o new file mode 100644 index 0000000..8e3aec9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcenc.o new file mode 100644 index 0000000..236230c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctr.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctr.o new file mode 100644 index 0000000..fdeb9d0 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctrcbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctrcbc.o new file mode 100644 index 0000000..92a8bba Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctrcbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_dec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_dec.o new file mode 100644 index 0000000..dcc7d1f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_dec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_enc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_enc.o new file mode 100644 index 0000000..ffb624c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct64_enc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcdec.o new file mode 100644 index 0000000..1ec830c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcenc.o new file mode 100644 index 0000000..f75ce68 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_ctr.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_ctr.o new file mode 100644 index 0000000..cdef65a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_ctr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_ctrcbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_ctrcbc.o new file mode 100644 index 0000000..c904ad6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_ctrcbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_dec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_dec.o new file mode 100644 index 0000000..aa6f36d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_dec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_enc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_enc.o new file mode 100644 index 0000000..eb68bc9 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_ct_enc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8.o new file mode 100644 index 0000000..875a37e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcdec.o new file mode 100644 index 0000000..b880376 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcenc.o new file mode 100644 index 0000000..a6dec4c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctr.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctr.o new file mode 100644 index 0000000..ea0724d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctrcbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctrcbc.o new file mode 100644 index 0000000..30ad0f4 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctrcbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_cbcdec.o new file mode 100644 index 0000000..daa032f Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_cbcenc.o new file mode 100644 index 0000000..9a0e3a6 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_ctr.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_ctr.o new file mode 100644 index 0000000..44dcbde Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_ctr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_ctrcbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_ctrcbc.o new file mode 100644 index 0000000..dc27787 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_ctrcbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_dec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_dec.o new file mode 100644 index 0000000..d892900 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_dec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_enc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_enc.o new file mode 100644 index 0000000..c16fd1b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_small_enc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni.o new file mode 100644 index 0000000..db4918b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcdec.o new file mode 100644 index 0000000..5db5adf Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcenc.o new file mode 100644 index 0000000..2264104 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctr.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctr.o new file mode 100644 index 0000000..499b2e8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctr.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctrcbc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctrcbc.o new file mode 100644 index 0000000..e0c2fbe Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctrcbc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/chacha20_ct.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/chacha20_ct.o new file mode 100644 index 0000000..ec36860 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/chacha20_ct.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/chacha20_sse2.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/chacha20_sse2.o new file mode 100644 index 0000000..88534f1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/chacha20_sse2.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct.o new file mode 100644 index 0000000..41939f7 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct_cbcdec.o new file mode 100644 index 0000000..feb8df2 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct_cbcenc.o new file mode 100644 index 0000000..2f7a494 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_ct_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_support.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_support.o new file mode 100644 index 0000000..3fc8bda Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_support.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab.o new file mode 100644 index 0000000..fcfa80e Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab_cbcdec.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab_cbcdec.o new file mode 100644 index 0000000..792c143 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab_cbcdec.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab_cbcenc.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab_cbcenc.o new file mode 100644 index 0000000..fcafd0d Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/des_tab_cbcenc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul.o new file mode 100644 index 0000000..8f9bcf7 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul32.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul32.o new file mode 100644 index 0000000..2147cad Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul32.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmulq.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmulq.o new file mode 100644 index 0000000..11568af Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_ctmulq.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_i15.o b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_i15.o new file mode 100644 index 0000000..1306b35 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/symcipher/poly1305_i15.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/asn1enc.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/asn1enc.o new file mode 100644 index 0000000..335d162 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/asn1enc.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_ec_pk8der.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_ec_pk8der.o new file mode 100644 index 0000000..4e77650 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_ec_pk8der.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_ec_rawder.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_ec_rawder.o new file mode 100644 index 0000000..1696a1b Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_ec_rawder.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_rsa_pk8der.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_rsa_pk8der.o new file mode 100644 index 0000000..83bc9ba Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_rsa_pk8der.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_rsa_rawder.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_rsa_rawder.o new file mode 100644 index 0000000..d364e70 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/encode_rsa_rawder.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/skey_decoder.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/skey_decoder.o new file mode 100644 index 0000000..04bf5cc Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/skey_decoder.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_decoder.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_decoder.o new file mode 100644 index 0000000..05797dc Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_decoder.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_knownkey.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_knownkey.o new file mode 100644 index 0000000..ad1f175 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_knownkey.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_minimal.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_minimal.o new file mode 100644 index 0000000..9ae0923 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_minimal.o differ diff --git a/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_minimal_full.o b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_minimal_full.o new file mode 100644 index 0000000..eb7cc2c Binary files /dev/null and b/clavis/clavis-cli/build/vendor/bearssl/src/x509/x509_minimal_full.o differ diff --git a/clavis/clavis-cli/build/vendor/cjson/cJSON.o b/clavis/clavis-cli/build/vendor/cjson/cJSON.o new file mode 100644 index 0000000..7de17c1 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/cjson/cJSON.o differ diff --git a/clavis/clavis-cli/build/vendor/quickjs/cutils.o b/clavis/clavis-cli/build/vendor/quickjs/cutils.o new file mode 100644 index 0000000..eaa5f69 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/quickjs/cutils.o differ diff --git a/clavis/clavis-cli/build/vendor/quickjs/dtoa.o b/clavis/clavis-cli/build/vendor/quickjs/dtoa.o new file mode 100644 index 0000000..9e701f2 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/quickjs/dtoa.o differ diff --git a/clavis/clavis-cli/build/vendor/quickjs/libregexp.o b/clavis/clavis-cli/build/vendor/quickjs/libregexp.o new file mode 100644 index 0000000..e07a324 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/quickjs/libregexp.o differ diff --git a/clavis/clavis-cli/build/vendor/quickjs/libunicode.o b/clavis/clavis-cli/build/vendor/quickjs/libunicode.o new file mode 100644 index 0000000..247a394 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/quickjs/libunicode.o differ diff --git a/clavis/clavis-cli/build/vendor/quickjs/quickjs-libc.o b/clavis/clavis-cli/build/vendor/quickjs/quickjs-libc.o new file mode 100644 index 0000000..17c2bf8 Binary files /dev/null and b/clavis/clavis-cli/build/vendor/quickjs/quickjs-libc.o differ diff --git a/clavis/clavis-cli/build/vendor/quickjs/quickjs.o b/clavis/clavis-cli/build/vendor/quickjs/quickjs.o new file mode 100644 index 0000000..e71b22a Binary files /dev/null and b/clavis/clavis-cli/build/vendor/quickjs/quickjs.o differ diff --git a/clavis/clavis-cli/clavitor-cli b/clavis/clavis-cli/clavitor-cli new file mode 100755 index 0000000..bc51aaf Binary files /dev/null and b/clavis/clavis-cli/clavitor-cli differ diff --git a/clavis/clavis-cli/jsconfig.json b/clavis/clavis-cli/jsconfig.json new file mode 100644 index 0000000..c8d781d --- /dev/null +++ b/clavis/clavis-cli/jsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ES2020", + "lib": ["ES2020", "DOM"], + "allowJs": true, + "checkJs": false, + "noEmit": true, + "strict": false, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "baseUrl": ".", + "paths": { + "crypto/*": ["../clavis-crypto/*"] + } + }, + "include": [ + "src/**/*", + "../clavis-crypto/**/*.js" + ], + "exclude": [ + "vendor/**/*" + ], + "typeAcquisition": { + "include": ["clavitor"] + } +} diff --git a/clavis/clavis-cli/types/clavitor.d.ts b/clavis/clavis-cli/types/clavitor.d.ts new file mode 100644 index 0000000..42bfde7 --- /dev/null +++ b/clavis/clavis-cli/types/clavitor.d.ts @@ -0,0 +1,48 @@ +/* + * clavitor — TypeScript declarations for shared crypto modules + * Provides intellisense for JS files in both QuickJS (CLI) and browser environments + */ + +/* Environment detection */ +declare const IS_BROWSER: boolean; + +/* --- QuickJS Native Functions (injected by jsbridge.c) --- */ +declare function native_base64_encode(bytes: Uint8Array): string; +declare function native_base64_decode(str: string): Uint8Array; +declare function native_aes_gcm_encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array; +declare function native_aes_gcm_decrypt(key: Uint8Array, iv: Uint8Array, ciphertext: Uint8Array): Uint8Array; +declare function native_aes_gcm_decrypt_blob(key: Uint8Array, data: Uint8Array): Uint8Array; +declare function native_hkdf_sha256(ikm: Uint8Array, salt: Uint8Array | null, info: Uint8Array, length: number): Uint8Array; +declare function native_hmac_sha1(key: Uint8Array, data: Uint8Array): Uint8Array; +declare function native_encode_utf8(str: string): Uint8Array; +declare function native_decode_utf8(bytes: Uint8Array): string; +declare function native_random_bytes(n: number): Uint8Array; + +/* --- clavitor namespace (populated by crypto.js and totp.js) --- */ +interface ClavitorCrypto { + aes_gcm_encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array | Promise; + aes_gcm_decrypt(key: Uint8Array, data: Uint8Array): Uint8Array | Promise; + hkdf_sha256(ikm: Uint8Array, salt: Uint8Array | null, info: Uint8Array, length: number): Uint8Array | Promise; + encrypt_field(key: Uint8Array, field_label: string, plaintext: string): string | Promise; + decrypt_field(key: Uint8Array, field_label: string, ciphertext_b64: string): string | Promise; + l2_encrypt_field(key: Uint8Array, entry_id: string, label: string, pt: string): string | Promise; + l2_decrypt_field(key: Uint8Array, entry_id: string, label: string, ct: string): string | Promise; + uint8_to_base64(bytes: Uint8Array): string; + base64_to_uint8(str: string): Uint8Array; +} + +interface ClavitorTOTP { + generate_totp(secret_b32: string, time?: number, period?: number, digits?: number): string | Promise; + totp_remaining(period?: number): number; + base32_decode(input: string): Uint8Array; +} + +interface ClavitorNamespace { + crypto: ClavitorCrypto; + totp: ClavitorTOTP; +} + +declare const clavitor: ClavitorNamespace; + +/* Test result global (set by test_crypto.js) */ +declare const _clavitor_test_result: string | undefined; diff --git a/clavis/clavis-vault/api/handlers.go b/clavis/clavis-vault/api/handlers.go index 3c13326..7a77144 100644 --- a/clavis/clavis-vault/api/handlers.go +++ b/clavis/clavis-vault/api/handlers.go @@ -8,7 +8,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "io" "log" "net/http" "path/filepath" @@ -876,185 +875,6 @@ func (h *Handlers) MatchURL(w http.ResponseWriter, r *http.Request) { } -// --------------------------------------------------------------------------- -// Import -// --------------------------------------------------------------------------- - -// ImportEntries parses known formats directly; falls back to chunked LLM for unknown formats. -func (h *Handlers) ImportEntries(w http.ResponseWriter, r *http.Request) { - actor := ActorFromContext(r.Context()) - - if err := r.ParseMultipartForm(32 << 20); err != nil { - ErrorResponse(w, http.StatusBadRequest, "invalid_form", "Failed to parse form") - return - } - file, _, err := r.FormFile("file") - if err != nil { - ErrorResponse(w, http.StatusBadRequest, "missing_file", "File is required") - return - } - defer file.Close() - - content, err := io.ReadAll(file) - if err != nil { - ErrorResponse(w, http.StatusInternalServerError, "read_failed", "Failed to read file") - return - } - - var entries []lib.VaultData - if parsed, ok := lib.DetectAndParse(content); ok { - entries = parsed - } else { - ErrorResponse(w, http.StatusBadRequest, "unknown_format", "Unsupported import format. Supported: Chrome CSV, Firefox CSV, Bitwarden JSON, Proton Pass JSON") - return - } - - // Classify entries against existing vault - existingAll, _ := lib.EntryList(h.db(r), h.vk(r), nil) - existingIndex := map[string]lib.HexID{} - for _, e := range existingAll { - if e.VaultData == nil { - continue - } - existingIndex[importDedupKey(e.VaultData)] = e.EntryID - } - - type PreviewEntry struct { - lib.VaultData - Status string `json:"status"` - ExistingID lib.HexID `json:"existing_id,omitempty"` - } - - batchSeen := map[string]bool{} - preview := make([]PreviewEntry, 0, len(entries)) - for _, vd := range entries { - key := importDedupKey(&vd) - pe := PreviewEntry{VaultData: vd} - if batchSeen[key] { - pe.Status = "duplicate" - } else if existingID, found := existingIndex[key]; found { - pe.Status = "update" - pe.ExistingID = existingID - } else { - pe.Status = "new" - } - batchSeen[key] = true - preview = append(preview, pe) - } - - newCount, updateCount, dupCount := 0, 0, 0 - for _, pe := range preview { - switch pe.Status { - case "new": - newCount++ - case "update": - updateCount++ - case "duplicate": - dupCount++ - } - } - - // Return first 100 for preview UI; client confirms all - previewSlice := preview - if len(previewSlice) > 100 { - previewSlice = previewSlice[:100] - } - - lib.AuditLog(h.db(r), &lib.AuditEvent{ - Action: lib.ActionImport, - Actor: actor, - IPAddr: realIP(r), - Title: fmt.Sprintf("%d parsed: %d new, %d update, %d duplicate", len(entries), newCount, updateCount, dupCount), - }) - - JSONResponse(w, http.StatusOK, map[string]any{ - "entries": previewSlice, - "all_entries": preview, // full list for confirm - "total": len(preview), - "new": newCount, - "update": updateCount, - "duplicates": dupCount, - }) -} - -// ImportConfirm confirms and saves imported entries. -func (h *Handlers) ImportConfirm(w http.ResponseWriter, r *http.Request) { - actor := ActorFromContext(r.Context()) - - var req struct { - Entries []lib.VaultData `json:"entries"` - } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - ErrorResponse(w, http.StatusBadRequest, "invalid_json", "Invalid request body") - return - } - - // Build dedup index: normalized "url|username" → existing Entry (for upsert) - existing, _ := lib.EntryList(h.db(r), h.vk(r), nil) - dedupIndex := map[string]*lib.Entry{} - for i, e := range existing { - if e.VaultData == nil { - continue - } - dedupIndex[importDedupKey(e.VaultData)] = &existing[i] - } - - var created, updated, skipped int - // Track intra-batch keys to avoid importing same entry twice - batchSeen := map[string]bool{} - for _, vd := range req.Entries { - key := importDedupKey(&vd) - if batchSeen[key] { - continue // intra-batch duplicate — first occurrence wins within same batch - } - batchSeen[key] = true - - vdCopy := vd - if existingEntry, found := dedupIndex[key]; found { - // Collision: keep newest by source modification date. - // If incoming has no date (e.g. Chrome CSV) → don't overwrite. - // If incoming date > existing → overwrite. - incomingMod := vdCopy.SourceModified - existingMod := existingEntry.UpdatedAt - shouldUpdate := incomingMod > 0 && incomingMod > existingMod - if shouldUpdate { - existingEntry.Title = vdCopy.Title - existingEntry.Type = vdCopy.Type - existingEntry.VaultData = &vdCopy - if err := lib.EntryUpdate(h.db(r), h.vk(r), existingEntry); err == nil { - updated++ - } - } else if incomingMod == 0 { - // No date in source — skip, existing wins - skipped++ - } else { - // Existing is newer — skip - skipped++ - } - } else { - entry := &lib.Entry{ - Type: vdCopy.Type, - Title: vdCopy.Title, - DataLevel: lib.DataLevelL1, - VaultData: &vdCopy, - } - if err := lib.EntryCreate(h.db(r), h.vk(r), entry); err == nil { - created++ - dedupIndex[key] = entry - } - } - } - - lib.AuditLog(h.db(r), &lib.AuditEvent{ - Action: lib.ActionImport, - Actor: actor, - IPAddr: realIP(r), - Title: fmt.Sprintf("%d created, %d updated, %d skipped (date-based)", created, updated, skipped), - }) - - JSONResponse(w, http.StatusOK, map[string]any{"imported": created, "updated": updated, "skipped": skipped}) -} - // --------------------------------------------------------------------------- // Audit Log // --------------------------------------------------------------------------- @@ -1255,39 +1075,6 @@ func stripL2Fields(vd *lib.VaultData) { } } -// normalizeURLForDedup strips scheme differences, trailing slashes, and lowercases -// so that "http://x.com/" and "https://x.com" produce the same dedup key. -func normalizeURLForDedup(u string) string { - u = strings.ToLower(u) - u = strings.TrimPrefix(u, "https://") - u = strings.TrimPrefix(u, "http://") - u = strings.TrimRight(u, "/") - return u -} - -// importDedupKey builds a dedup key from a VaultData's first URL + username. -// For notes/entries without URLs or usernames, fall back to the title to avoid -// all notes colliding on the same empty key. -func importDedupKey(vd *lib.VaultData) string { - var url, username string - if len(vd.URLs) > 0 { - url = normalizeURLForDedup(vd.URLs[0]) - } - for _, f := range vd.Fields { - lbl := strings.ToLower(f.Label) - if lbl == "username" || lbl == "email" || lbl == "login" { - username = strings.ToLower(f.Value) - break - } - } - key := url + "|" + username - if key == "|" { - // No URL and no username — use title to differentiate. - key = "title:" + strings.ToLower(vd.Title) - } - return key -} - func extractDomain(urlStr string) string { // Simple domain extraction urlStr = strings.TrimPrefix(urlStr, "https://") diff --git a/clavis/clavis-vault/api/integration_test.go b/clavis/clavis-vault/api/integration_test.go index 9ae3e9e..8b968a0 100644 --- a/clavis/clavis-vault/api/integration_test.go +++ b/clavis/clavis-vault/api/integration_test.go @@ -16,7 +16,6 @@ import ( "encoding/base64" "encoding/json" "io" - "mime/multipart" "net/http" "net/http/httptest" "strings" @@ -423,56 +422,6 @@ func TestURLMatch_no_match(t *testing.T) { } } -// --------------------------------------------------------------------------- -// Import -// --------------------------------------------------------------------------- - -func TestImport_ChromeCSV(t *testing.T) { - c := newTestClient(t) - - csv := "name,url,username,password\nGitHub,https://github.com,octocat,hunter2\n" - body := &bytes.Buffer{} - w := multipart.NewWriter(body) - part, _ := w.CreateFormFile("file", "passwords.csv") - part.Write([]byte(csv)) - w.Close() - - req, _ := http.NewRequest("POST", c.srv.URL+"/api/import", body) - req.Header.Set("Content-Type", w.FormDataContentType()) - req.Header.Set("Authorization", "Bearer "+c.bearer) - resp, err := c.srv.Client().Do(req) - if err != nil { - t.Fatal(err) - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - b, _ := io.ReadAll(resp.Body) - t.Fatalf("import returned %d: %s", resp.StatusCode, b) - } -} - -func TestImport_unknown_format_rejected(t *testing.T) { - c := newTestClient(t) - - body := &bytes.Buffer{} - w := multipart.NewWriter(body) - part, _ := w.CreateFormFile("file", "garbage.txt") - part.Write([]byte("this is not a password export")) - w.Close() - - req, _ := http.NewRequest("POST", c.srv.URL+"/api/import", body) - req.Header.Set("Content-Type", w.FormDataContentType()) - req.Header.Set("Authorization", "Bearer "+c.bearer) - resp, err := c.srv.Client().Do(req) - if err != nil { - t.Fatal(err) - } - defer resp.Body.Close() - if resp.StatusCode != 400 { - t.Errorf("unknown format should return 400, got %d", resp.StatusCode) - } -} - // --------------------------------------------------------------------------- // Password Generator // --------------------------------------------------------------------------- diff --git a/clavis/clavis-vault/api/middleware.go b/clavis/clavis-vault/api/middleware.go index 0228cad..f6acec8 100644 --- a/clavis/clavis-vault/api/middleware.go +++ b/clavis/clavis-vault/api/middleware.go @@ -396,6 +396,47 @@ func JSONResponse(w http.ResponseWriter, status int, data any) { json.NewEncoder(w).Encode(data) } +// tarpitHandler holds unrecognized requests for 30 seconds. +// Drips one byte per second to keep the connection alive and waste +// scanner resources. Capped at 1000 concurrent tarpit slots — +// beyond that, connections are dropped immediately. +var ( + tarpitSem = make(chan struct{}, 1000) +) + +func tarpitHandler(w http.ResponseWriter, r *http.Request) { + select { + case tarpitSem <- struct{}{}: + defer func() { <-tarpitSem }() + default: + // Tarpit full — drop immediately, no response + if hj, ok := w.(http.Hijacker); ok { + conn, _, err := hj.Hijack() + if err == nil { + conn.Close() + } + } + return + } + + log.Printf("tarpit: %s %s from %s", r.Method, r.URL.Path, realIP(r)) + + // Chunked response: drip one space per second for 30s + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(200) + flusher, canFlush := w.(http.Flusher) + for i := 0; i < 30; i++ { + _, err := w.Write([]byte(" ")) + if err != nil { + return // client gave up + } + if canFlush { + flusher.Flush() + } + time.Sleep(time.Second) + } +} + func realIP(r *http.Request) string { if xff := r.Header.Get("X-Forwarded-For"); xff != "" { parts := strings.SplitN(xff, ",", 2) diff --git a/clavis/clavis-vault/api/routes.go b/clavis/clavis-vault/api/routes.go index 60923f5..5659be8 100644 --- a/clavis/clavis-vault/api/routes.go +++ b/clavis/clavis-vault/api/routes.go @@ -61,6 +61,57 @@ func NewRouter(cfg *lib.Config, webFS embed.FS) *chi.Mux { r.Handle("/app/*", http.StripPrefix("/app", appServer)) } + // --- Root-level: minimal, disclose nothing --- + // Legitimate browser/crawler requests get a fast, empty response. + // Everything else hits the tarpit (30s slow drain). + + favicon, _ := fs.ReadFile(webFS, "web/favicon.svg") + serveFavicon := func(w http.ResponseWriter, r *http.Request) { + if favicon != nil { + w.Header().Set("Content-Type", "image/svg+xml") + w.Header().Set("Cache-Control", "public, max-age=86400") + w.Write(favicon) + } else { + w.WriteHeader(204) + } + } + nothing := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) } + disallow := func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("User-agent: *\nDisallow: /\n")) + } + + r.Get("/", nothing) + r.Get("/favicon.ico", serveFavicon) + r.Get("/favicon.svg", serveFavicon) + r.Get("/robots.txt", disallow) + r.Get("/sitemap.xml", nothing) + r.Get("/sitemap.xml.gz", nothing) + r.Get("/sitemap-index.xml", nothing) + r.Get("/ads.txt", nothing) + r.Get("/app-ads.txt", nothing) + r.Get("/manifest.json", nothing) + r.Get("/browserconfig.xml", nothing) + r.Get("/crossdomain.xml", nothing) + r.Get("/humans.txt", nothing) + r.Get("/security.txt", nothing) + r.Get("/apple-touch-icon.png", nothing) + r.Get("/apple-touch-icon-precomposed.png", nothing) + r.Get("/.well-known/security.txt", nothing) + r.Get("/.well-known/acme-challenge/*", nothing) + r.Get("/.well-known/change-password", nothing) + r.Get("/.well-known/openid-configuration", nothing) + r.Get("/.well-known/webfinger", nothing) + r.Get("/.well-known/assetlinks.json", nothing) + r.Get("/.well-known/apple-app-site-association", nothing) + r.Get("/.well-known/mta-sts.txt", nothing) + r.Get("/.well-known/nodeinfo", nothing) + + // Tarpit: everything not registered above. + // Hold the connection for 30s, drip slowly, waste scanner resources. + r.NotFound(tarpitHandler) + r.MethodNotAllowed(tarpitHandler) + return r } @@ -82,10 +133,6 @@ func mountAPIRoutes(r chi.Router, h *Handlers) { // Password generator r.Get("/generate", h.GeneratePassword) - // Import - r.Post("/import", h.ImportEntries) - r.Post("/import/confirm", h.ImportConfirm) - // Audit log r.Get("/audit", h.GetAuditLog) diff --git a/clavis/clavis-vault/clavitor-linux-amd64 b/clavis/clavis-vault/clavitor-linux-amd64 index 6cc74f8..59d373b 100755 Binary files a/clavis/clavis-vault/clavitor-linux-amd64 and b/clavis/clavis-vault/clavitor-linux-amd64 differ diff --git a/clavis/clavis-vault/cmd/clavitor/main.go b/clavis/clavis-vault/cmd/clavitor/main.go index 8a8c3d4..89cfdea 100644 --- a/clavis/clavis-vault/cmd/clavitor/main.go +++ b/clavis/clavis-vault/cmd/clavitor/main.go @@ -24,7 +24,7 @@ var ( func main() { api.Version = version + " (" + commit + " " + buildDate + ")" - port := flag.Int("port", envInt("PORT", 1984), "Listen port") + port := flag.Int("port", envInt("PORT", 443), "Listen port") telemetryFreq := flag.Int("telemetry-freq", envInt("TELEMETRY_FREQ", 0), "Telemetry POST interval in seconds (0 = disabled)") telemetryHost := flag.String("telemetry-host", envStr("TELEMETRY_HOST", ""), "Telemetry endpoint URL") telemetryToken := flag.String("telemetry-token", envStr("TELEMETRY_TOKEN", ""), "Bearer token for telemetry endpoint") diff --git a/clavis/clavis-vault/lib/config.go b/clavis/clavis-vault/lib/config.go index bb49bc2..25f162d 100644 --- a/clavis/clavis-vault/lib/config.go +++ b/clavis/clavis-vault/lib/config.go @@ -19,7 +19,7 @@ func LoadConfig() (*Config, error) { } return &Config{ - Port: "1984", + Port: "443", DataDir: dataDir, SessionTTL: 86400, }, nil diff --git a/clavitor.com/._.DS_Store b/clavitor.com/._.DS_Store deleted file mode 100644 index 28c42fb..0000000 Binary files a/clavitor.com/._.DS_Store and /dev/null differ diff --git a/clavitor.com/._clavitor-logo.svg b/clavitor.com/._clavitor-logo.svg deleted file mode 100644 index 1a09082..0000000 Binary files a/clavitor.com/._clavitor-logo.svg and /dev/null differ diff --git a/clavitor.com/account/account.css b/clavitor.com/account/account.css deleted file mode 100644 index b5a9eeb..0000000 --- a/clavitor.com/account/account.css +++ /dev/null @@ -1,802 +0,0 @@ -/* clavitor account — 2027 */ - -:root { - --bg: #060a10; - --bg-subtle: #0a1018; - --surface: rgba(255,255,255,0.03); - --surface-hover: rgba(255,255,255,0.06); - --surface-active: rgba(255,255,255,0.08); - --glass: rgba(12,18,30,0.7); - --glass-border: rgba(255,255,255,0.06); - --glass-border-hover: rgba(255,255,255,0.12); - - --text: #f1f5f9; - --text-secondary: #b0bec5; - --text-tertiary: #8a9bb0; - - --accent: #4ade80; - --accent-dim: rgba(74,222,128,0.12); - --accent-glow: rgba(74,222,128,0.25); - --gold: #D4AF37; - --gold-dim: rgba(212,175,55,0.12); - --red: #ef4444; - --red-dim: rgba(239,68,68,0.12); - - --radius: 1rem; - --radius-sm: 0.625rem; - --radius-xs: 0.375rem; - - --font: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; - --mono: 'JetBrains Mono', 'SF Mono', monospace; - - --ease: cubic-bezier(0.16, 1, 0.3, 1); - --ease-out: cubic-bezier(0, 0, 0.2, 1); -} - -*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } - -html { - font-size: 16px; - scroll-behavior: smooth; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -body { - font-family: var(--font); - background: var(--bg); - color: var(--text); - line-height: 1.6; - min-height: 100vh; - overflow-x: hidden; -} - -/* ── Ambient background ── */ - -.ambient { - position: fixed; - inset: 0; - z-index: -1; - overflow: hidden; - pointer-events: none; -} - -.ambient::before { - content: ''; - position: absolute; - width: 800px; - height: 800px; - top: -200px; - right: -200px; - background: radial-gradient(circle, rgba(74,222,128,0.04) 0%, transparent 70%); - animation: drift 25s ease-in-out infinite alternate; -} - -.ambient::after { - content: ''; - position: absolute; - width: 600px; - height: 600px; - bottom: -100px; - left: -150px; - background: radial-gradient(circle, rgba(212,175,55,0.03) 0%, transparent 70%); - animation: drift 30s ease-in-out infinite alternate-reverse; -} - -@keyframes drift { - 0% { transform: translate(0, 0) scale(1); } - 100% { transform: translate(60px, 40px) scale(1.1); } -} - -/* ── Grid lines (subtle background texture) ── */ - -.gridlines { - position: fixed; - inset: 0; - z-index: -1; - pointer-events: none; - background-image: - linear-gradient(rgba(255,255,255,0.015) 1px, transparent 1px), - linear-gradient(90deg, rgba(255,255,255,0.015) 1px, transparent 1px); - background-size: 80px 80px; - mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, black 20%, transparent 100%); -} - -/* ── Layout ── */ - -.page { - display: flex; - flex-direction: column; - min-height: 100vh; -} - -.container { - width: 100%; - max-width: 960px; - margin: 0 auto; - padding: 0 1.5rem; -} - -.container-narrow { - max-width: 480px; -} - -/* ── Topbar ── */ - -.topbar { - position: sticky; - top: 0; - z-index: 100; - padding: 0.875rem 0; - background: rgba(6,10,16,0.8); - backdrop-filter: blur(20px) saturate(1.2); - -webkit-backdrop-filter: blur(20px) saturate(1.2); - border-bottom: 1px solid var(--glass-border); -} - -.topbar-inner { - display: flex; - align-items: center; - justify-content: space-between; -} - -.topbar-brand { - font-family: var(--mono); - font-size: 0.875rem; - font-weight: 600; - color: var(--text); - text-decoration: none; - letter-spacing: -0.02em; - display: flex; - align-items: center; - gap: 0.5rem; -} - -.topbar-brand .port { - color: var(--text-tertiary); - font-weight: 400; -} - -.topbar-nav { - display: flex; - align-items: center; - gap: 0.25rem; -} - -.topbar-nav a { - font-size: 0.8125rem; - color: var(--text-secondary); - text-decoration: none; - padding: 0.375rem 0.75rem; - border-radius: var(--radius-xs); - transition: all 0.2s var(--ease); -} - -.topbar-nav a:hover { color: var(--text); background: var(--surface-hover); } -.topbar-nav a.active { color: var(--text); background: var(--surface-active); } - -.topbar-nav .separator { - width: 1px; - height: 1rem; - background: var(--glass-border); - margin: 0 0.375rem; -} - -/* ── Typography ── */ - -h1 { - font-size: clamp(1.75rem, 3.5vw, 2.5rem); - font-weight: 700; - letter-spacing: -0.03em; - line-height: 1.15; -} - -h2 { - font-size: 1.25rem; - font-weight: 600; - letter-spacing: -0.02em; - line-height: 1.3; -} - -h3 { - font-size: 1rem; - font-weight: 600; - letter-spacing: -0.01em; -} - -.label { - font-family: var(--mono); - font-size: 0.6875rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.1em; - color: var(--text-secondary); -} - -.label.accent { color: var(--accent); } -.label.gold { color: var(--gold); } -.label.red { color: var(--red); } - -.mono { font-family: var(--mono); } - -.text-secondary { color: var(--text-secondary); } -.text-accent { color: var(--accent); } -.text-gold { color: var(--gold); } - -/* ── Buttons ── */ - -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - font-family: var(--font); - font-size: 0.875rem; - font-weight: 550; - padding: 0.6875rem 1.375rem; - border-radius: var(--radius-sm); - border: none; - cursor: pointer; - text-decoration: none; - transition: all 0.25s var(--ease); - outline: none; - position: relative; - overflow: hidden; -} - -.btn:focus-visible { - box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent); -} - -.btn-primary { - background: var(--accent); - color: #0a0f14; -} - -.btn-primary:hover { - background: #6ee7a0; - transform: translateY(-1px); - box-shadow: 0 4px 20px var(--accent-glow); -} - -.btn-primary:active { transform: translateY(0); } - -.btn-ghost { - background: var(--surface); - color: var(--text-secondary); - border: 1px solid var(--glass-border); -} - -.btn-ghost:hover { - color: var(--text); - background: var(--surface-hover); - border-color: var(--glass-border-hover); -} - -.btn-danger { - background: var(--red-dim); - color: var(--red); - border: 1px solid rgba(239,68,68,0.15); -} - -.btn-danger:hover { - background: rgba(239,68,68,0.18); - border-color: rgba(239,68,68,0.3); -} - -.btn-block { width: 100%; } - -.btn-lg { - padding: 0.875rem 1.75rem; - font-size: 0.9375rem; -} - -.btn .icon { - width: 1rem; - height: 1rem; - flex-shrink: 0; -} - -/* ── Cards ── */ - -.card { - background: var(--surface); - border: 1px solid var(--glass-border); - border-radius: var(--radius); - padding: 1.5rem; - transition: all 0.3s var(--ease); -} - -.card-interactive { - cursor: pointer; -} - -.card-interactive:hover { - background: var(--surface-hover); - border-color: var(--glass-border-hover); - transform: translateY(-2px); - box-shadow: 0 8px 32px rgba(0,0,0,0.3); -} - -.card-interactive:active { transform: translateY(0); } - -.card-glow:hover { - box-shadow: 0 8px 32px rgba(0,0,0,0.3), 0 0 0 1px var(--accent-dim); -} - -.card-gold { - border-color: rgba(212,175,55,0.15); -} - -.card-gold:hover { - border-color: rgba(212,175,55,0.3); - box-shadow: 0 8px 32px rgba(0,0,0,0.3), 0 0 0 1px var(--gold-dim); -} - -/* ── Glass panels ── */ - -.glass { - background: var(--glass); - backdrop-filter: blur(24px) saturate(1.3); - -webkit-backdrop-filter: blur(24px) saturate(1.3); - border: 1px solid var(--glass-border); - border-radius: var(--radius); -} - -/* ── Forms ── */ - -.field { margin-bottom: 1.25rem; } - -.field label { - display: block; - font-size: 0.8125rem; - font-weight: 500; - color: var(--text-secondary); - margin-bottom: 0.5rem; -} - -.input { - width: 100%; - font-family: var(--font); - font-size: 0.9375rem; - padding: 0.75rem 1rem; - background: var(--surface); - border: 1px solid var(--glass-border); - border-radius: var(--radius-sm); - color: var(--text); - outline: none; - transition: all 0.2s var(--ease); -} - -.input::placeholder { color: var(--text-secondary); } - -.input:hover { border-color: var(--glass-border-hover); } - -.input:focus { - border-color: var(--accent); - box-shadow: 0 0 0 3px var(--accent-dim); -} - -.input-mono { - font-family: var(--mono); - font-size: 0.875rem; - letter-spacing: 0.02em; -} - -/* ── Status indicators ── */ - -.status-dot { - width: 0.5rem; - height: 0.5rem; - border-radius: 50%; - flex-shrink: 0; -} - -.status-dot.live { - background: var(--accent); - box-shadow: 0 0 8px var(--accent-glow); - animation: pulse-live 2s ease-in-out infinite; -} - -.status-dot.expired { - background: var(--red); - box-shadow: 0 0 8px rgba(239,68,68,0.3); -} - -.status-dot.pending { - background: var(--gold); - box-shadow: 0 0 8px rgba(212,175,55,0.3); - animation: pulse-live 2s ease-in-out infinite; -} - -@keyframes pulse-live { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.5; } -} - -/* ── Region cards ── */ - -.region-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 0.75rem; -} - -.region-card { - display: flex; - flex-direction: column; - gap: 0.5rem; - padding: 1.125rem; -} - -.region-card .region-name { - font-weight: 600; - font-size: 0.9375rem; -} - -.region-card .region-location { - font-size: 0.8125rem; - color: var(--text-secondary); -} - -.region-card .region-flag { - font-size: 1.25rem; - line-height: 1; -} - -.region-card.selected { - border-color: var(--accent); - background: var(--accent-dim); - box-shadow: 0 0 0 1px var(--accent-dim); -} - -.region-card.hq { - border-color: rgba(212,175,55,0.2); -} - -.region-card.hq .label { color: var(--gold); } - -/* ── Vault list ── */ - -.vault-row { - display: flex; - align-items: center; - gap: 1rem; - padding: 1rem 1.25rem; - border-bottom: 1px solid var(--glass-border); - transition: background 0.15s var(--ease); -} - -.vault-row:last-child { border-bottom: none; } -.vault-row:hover { background: var(--surface-hover); } - -.vault-id { - font-family: var(--mono); - font-size: 0.875rem; - font-weight: 500; - color: var(--text); -} - -.vault-region { - font-size: 0.8125rem; - color: var(--text-secondary); -} - -.vault-meta { - margin-left: auto; - display: flex; - align-items: center; - gap: 1rem; - font-size: 0.8125rem; - color: var(--text-secondary); -} - -/* ── Dividers ── */ - -.divider { - border: none; - height: 1px; - background: var(--glass-border); - margin: 2rem 0; -} - -/* ── Section spacing ── */ - -.section { - padding: 3rem 0; -} - -.section-header { - margin-bottom: 1.5rem; - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; -} - -/* ── Login page ── */ - -.login-wrapper { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; - padding: 2rem; -} - -.login-card { - width: 100%; - max-width: 400px; - padding: 2.5rem; -} - -.login-header { - text-align: center; - margin-bottom: 2rem; -} - -.login-header .brand { - font-family: var(--mono); - font-size: 1.125rem; - font-weight: 600; - letter-spacing: -0.02em; - margin-bottom: 0.5rem; -} - -.login-header p { - color: var(--text-secondary); - font-size: 0.875rem; -} - -.login-divider { - display: flex; - align-items: center; - gap: 1rem; - margin: 1.5rem 0; - color: var(--text-secondary); - font-size: 0.75rem; -} - -.login-divider::before, -.login-divider::after { - content: ''; - flex: 1; - height: 1px; - background: var(--glass-border); -} - -.login-footer { - text-align: center; - margin-top: 1.5rem; - font-size: 0.8125rem; - color: var(--text-secondary); -} - -.login-footer a { - color: var(--accent); - text-decoration: none; -} - -.login-footer a:hover { text-decoration: underline; } - -/* ── Checkout ── */ - -.checkout-wrapper { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; - padding: 2rem; -} - -.checkout-card { - width: 100%; - max-width: 480px; - padding: 2.5rem; -} - -.price-display { - display: flex; - align-items: baseline; - gap: 0.375rem; - margin: 1rem 0; -} - -.price-amount { - font-size: 2.5rem; - font-weight: 700; - letter-spacing: -0.03em; - color: var(--text); -} - -.price-period { - font-size: 1rem; - color: var(--text-secondary); -} - -.price-note { - font-size: 0.8125rem; - color: var(--text-secondary); - margin-bottom: 1.5rem; -} - -.feature-list { - list-style: none; - margin: 1.5rem 0; -} - -.feature-list li { - display: flex; - align-items: center; - gap: 0.625rem; - padding: 0.375rem 0; - font-size: 0.875rem; - color: var(--text-secondary); -} - -.feature-list .check { - color: var(--accent); - font-size: 0.75rem; - flex-shrink: 0; -} - -/* ── Settings ── */ - -.settings-section { - padding: 1.5rem 0; -} - -.settings-section + .settings-section { - border-top: 1px solid var(--glass-border); -} - -.settings-row { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; -} - -.settings-label { - font-size: 0.9375rem; - font-weight: 500; -} - -.settings-desc { - font-size: 0.8125rem; - color: var(--text-secondary); - margin-top: 0.25rem; -} - -/* ── Danger zone ── */ - -.danger-zone { - border: 1px solid rgba(239,68,68,0.15); - border-radius: var(--radius); - padding: 1.5rem; - margin-top: 1rem; -} - -.danger-zone h3 { - color: var(--red); - margin-bottom: 0.5rem; -} - -.danger-zone p { - font-size: 0.8125rem; - color: var(--text-secondary); - margin-bottom: 1rem; -} - -/* ── Passkey button ── */ - -.btn-passkey { - background: linear-gradient(135deg, rgba(74,222,128,0.1) 0%, rgba(74,222,128,0.05) 100%); - color: var(--accent); - border: 1px solid rgba(74,222,128,0.2); - font-weight: 600; -} - -.btn-passkey:hover { - background: linear-gradient(135deg, rgba(74,222,128,0.15) 0%, rgba(74,222,128,0.08) 100%); - border-color: rgba(74,222,128,0.35); - box-shadow: 0 4px 20px rgba(74,222,128,0.1); - transform: translateY(-1px); -} - -.btn-passkey:active { transform: translateY(0); } - -.passkey-icon { - width: 1.25rem; - height: 1.25rem; -} - -/* ── Toast / notification ── */ - -.toast { - position: fixed; - bottom: 1.5rem; - right: 1.5rem; - padding: 0.875rem 1.25rem; - border-radius: var(--radius-sm); - font-size: 0.8125rem; - font-weight: 500; - transform: translateY(120%); - opacity: 0; - transition: all 0.35s var(--ease); - z-index: 200; -} - -.toast.show { - transform: translateY(0); - opacity: 1; -} - -.toast.success { - background: var(--accent-dim); - color: var(--accent); - border: 1px solid rgba(74,222,128,0.2); -} - -.toast.error { - background: var(--red-dim); - color: var(--red); - border: 1px solid rgba(239,68,68,0.2); -} - -/* ── Skeleton loading ── */ - -.skeleton { - background: linear-gradient(90deg, var(--surface) 25%, var(--surface-hover) 50%, var(--surface) 75%); - background-size: 200% 100%; - animation: shimmer 1.5s ease-in-out infinite; - border-radius: var(--radius-xs); -} - -@keyframes shimmer { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } -} - -/* ── Responsive ── */ - -@media (max-width: 640px) { - .container { padding: 0 1rem; } - .login-card, .checkout-card { padding: 1.75rem; } - .region-grid { grid-template-columns: 1fr; } - .vault-row { flex-wrap: wrap; } - .vault-meta { margin-left: 0; width: 100%; justify-content: flex-start; } - .settings-row { flex-direction: column; align-items: flex-start; gap: 0.75rem; } - .topbar-nav { gap: 0; } -} - -/* ── Scrollbar ── */ - -::-webkit-scrollbar { width: 6px; } -::-webkit-scrollbar-track { background: transparent; } -::-webkit-scrollbar-thumb { background: var(--glass-border); border-radius: 3px; } -::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.12); } - -/* ── Selection ── */ - -::selection { background: var(--accent-dim); color: var(--text); } - -/* ── Focus management ── */ - -:focus:not(:focus-visible) { outline: none; } -:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } - -/* ── Transitions for page content ── */ - -.fade-in { - animation: fadeIn 0.4s var(--ease-out) both; -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(8px); } - to { opacity: 1; transform: translateY(0); } -} - -.fade-in-delay-1 { animation-delay: 0.05s; } -.fade-in-delay-2 { animation-delay: 0.1s; } -.fade-in-delay-3 { animation-delay: 0.15s; } diff --git a/clavitor.com/account/api.go b/clavitor.com/account/api.go deleted file mode 100644 index 7360009..0000000 --- a/clavitor.com/account/api.go +++ /dev/null @@ -1,306 +0,0 @@ -package main - -import ( - "crypto/rand" - "encoding/base64" - "encoding/json" - "log" - "net/http" - "strings" - "time" -) - -func randomToken(n int) string { - b := make([]byte, n) - rand.Read(b) - return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(b) -} - -func jsonResp(w http.ResponseWriter, status int, v any) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - json.NewEncoder(w).Encode(v) -} - -func jsonErr(w http.ResponseWriter, status int, msg string) { - jsonResp(w, status, map[string]string{"error": msg}) -} - -// Get email from session cookie -func authEmail(r *http.Request) string { - c, err := r.Cookie("v1984_session") - if err != nil { - return "" - } - email, err := sessionGet(c.Value) - if err != nil { - return "" - } - return email -} - -func setSessionCookie(w http.ResponseWriter, token string) { - http.SetCookie(w, &http.Cookie{ - Name: "v1984_session", - Value: token, - Path: "/", - HttpOnly: true, - Secure: true, - SameSite: http.SameSiteLaxMode, - MaxAge: 86400, - }) -} - -func clearSessionCookie(w http.ResponseWriter) { - http.SetCookie(w, &http.Cookie{ - Name: "v1984_session", - Value: "", - Path: "/", - HttpOnly: true, - Secure: true, - SameSite: http.SameSiteLaxMode, - MaxAge: -1, - }) -} - -// POST /api/auth/email — send login code (stubbed: always 123456) -func apiAuthEmail(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - jsonErr(w, 405, "method not allowed") - return - } - var req struct { - Email string `json:"email"` - } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Email == "" { - jsonErr(w, 400, "email required") - return - } - email := strings.ToLower(strings.TrimSpace(req.Email)) - - // Auto-create account if it doesn't exist - exists, _, _ := accountGet(email) - if !exists { - if err := accountCreate(email); err != nil { - log.Printf("account auto-create error: %v", err) - jsonErr(w, 500, "internal error") - return - } - log.Printf("account auto-created: %s", email) - } - - // Store code (stub: always 123456) - code := "123456" - if err := loginCodeSet(email, code); err != nil { - log.Printf("login code error: %v", err) - jsonErr(w, 500, "internal error") - return - } - - log.Printf("login code for %s: %s (stub — not emailed)", email, code) - jsonResp(w, 200, map[string]string{"status": "sent"}) -} - -// POST /api/auth/verify — verify login code -func apiAuthVerify(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - jsonErr(w, 405, "method not allowed") - return - } - var req struct { - Email string `json:"email"` - Code string `json:"code"` - } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Email == "" || req.Code == "" { - jsonErr(w, 400, "email and code required") - return - } - email := strings.ToLower(strings.TrimSpace(req.Email)) - - ok, err := loginCodeVerify(email, req.Code) - if err != nil || !ok { - jsonErr(w, 401, "invalid or expired code") - return - } - - token, err := sessionCreate(email) - if err != nil { - jsonErr(w, 500, "internal error") - return - } - - setSessionCookie(w, token) - jsonResp(w, 200, map[string]string{"status": "ok"}) -} - -// POST /api/auth/logout -func apiAuthLogout(w http.ResponseWriter, r *http.Request) { - if c, err := r.Cookie("v1984_session"); err == nil { - sessionDelete(c.Value) - } - clearSessionCookie(w) - jsonResp(w, 200, map[string]string{"status": "ok"}) -} - -// POST /api/checkout — create account (stub: no Stripe yet) -func apiCheckout(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - jsonErr(w, 405, "method not allowed") - return - } - var req struct { - Email string `json:"email"` - } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Email == "" { - jsonErr(w, 400, "email required") - return - } - email := strings.ToLower(strings.TrimSpace(req.Email)) - - // Create account (idempotent) - if err := accountCreate(email); err != nil { - log.Printf("account create error: %v", err) - jsonErr(w, 500, "internal error") - return - } - - // Auto-login after checkout (stub — real flow goes through Stripe first) - token, err := sessionCreate(email) - if err != nil { - jsonErr(w, 500, "internal error") - return - } - setSessionCookie(w, token) - - log.Printf("account created (stub): %s", email) - // In production: return Stripe checkout URL - // For now: redirect to regions page - jsonResp(w, 200, map[string]string{"url": basePath + "/regions"}) -} - -// GET /api/vaults — list vaults for authenticated user -func apiVaults(w http.ResponseWriter, r *http.Request) { - email := authEmail(r) - if email == "" { - jsonErr(w, 401, "not authenticated") - return - } - vaults, err := vaultList(email) - if err != nil { - jsonErr(w, 500, "internal error") - return - } - if vaults == nil { - vaults = []Vault{} - } - count, _ := vaultCount(email) - jsonResp(w, 200, map[string]any{ - "email": email, - "vaults": vaults, - "count": count, - "max": 1, // consumer: 1 vault - }) -} - -// POST /api/vault/create -func apiVaultCreate(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - jsonErr(w, 405, "method not allowed") - return - } - email := authEmail(r) - if email == "" { - jsonErr(w, 401, "not authenticated") - return - } - var req struct { - VaultID string `json:"vault_id"` - Region string `json:"region"` - } - if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Region == "" { - jsonErr(w, 400, "region required") - return - } - - // Check capacity - count, _ := vaultCount(email) - if count >= 1 { - jsonErr(w, 409, "vault limit reached") - return - } - - // Generate vault ID if not provided (normally comes from PRF on the POP) - vaultID := req.VaultID - if vaultID == "" { - vaultID = randomToken(4)[:6] // 6 chars, stub - } - - if err := vaultCreate(vaultID, email, req.Region); err != nil { - log.Printf("vault create error: %v", err) - jsonErr(w, 500, "internal error") - return - } - - log.Printf("vault created: %s for %s in %s", vaultID, email, req.Region) - jsonResp(w, 201, map[string]string{ - "vault_id": vaultID, - "region": req.Region, - "expires_at": time.Now().AddDate(1, 0, 0).UTC().Format(time.RFC3339), - }) -} - -// POST /api/vault/{id}/delete -func apiVaultDelete(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - jsonErr(w, 405, "method not allowed") - return - } - email := authEmail(r) - if email == "" { - jsonErr(w, 401, "not authenticated") - return - } - - // Extract vault ID from path: /api/vault/{id}/delete - parts := strings.Split(r.URL.Path, "/") - var vaultID string - for i, p := range parts { - if p == "vault" && i+1 < len(parts) { - vaultID = parts[i+1] - break - } - } - if vaultID == "" { - jsonErr(w, 400, "vault_id required") - return - } - - if err := vaultDelete(vaultID, email); err != nil { - jsonErr(w, 404, "vault not found") - return - } - - log.Printf("vault deleted: %s for %s", vaultID, email) - jsonResp(w, 200, map[string]string{"status": "deleted"}) -} - -// GET /api/account — account info -func apiAccount(w http.ResponseWriter, r *http.Request) { - email := authEmail(r) - if email == "" { - jsonErr(w, 401, "not authenticated") - return - } - exists, stripeID, _ := accountGet(email) - if !exists { - jsonErr(w, 404, "account not found") - return - } - count, _ := vaultCount(email) - jsonResp(w, 200, map[string]any{ - "email": email, - "stripe_id": stripeID, - "vaults": count, - "max": 1, - }) -} diff --git a/clavitor.com/account/clavitor-account b/clavitor.com/account/clavitor-account deleted file mode 100755 index 64fe26a..0000000 Binary files a/clavitor.com/account/clavitor-account and /dev/null differ diff --git a/clavitor.com/account/db.go b/clavitor.com/account/db.go deleted file mode 100644 index 21adc18..0000000 --- a/clavitor.com/account/db.go +++ /dev/null @@ -1,192 +0,0 @@ -package main - -import ( - "database/sql" - "log" - "time" - - _ "github.com/mattn/go-sqlite3" -) - -var db *sql.DB - -func initDB(path string) { - var err error - db, err = sql.Open("sqlite3", path+"?_journal=WAL&_busy_timeout=5000") - if err != nil { - log.Fatalf("db open: %v", err) - } - - migrations := []string{ - `CREATE TABLE IF NOT EXISTS accounts ( - email TEXT PRIMARY KEY, - stripe_id TEXT DEFAULT '', - created_at TEXT NOT NULL DEFAULT (datetime('now')) - )`, - `CREATE TABLE IF NOT EXISTS vaults ( - vault_id TEXT PRIMARY KEY, - account_email TEXT NOT NULL REFERENCES accounts(email), - region TEXT NOT NULL, - expires_at TEXT NOT NULL, - created_at TEXT NOT NULL DEFAULT (datetime('now')) - )`, - `CREATE TABLE IF NOT EXISTS sessions ( - token TEXT PRIMARY KEY, - email TEXT NOT NULL REFERENCES accounts(email), - expires_at TEXT NOT NULL, - created_at TEXT NOT NULL DEFAULT (datetime('now')) - )`, - `CREATE TABLE IF NOT EXISTS login_codes ( - email TEXT PRIMARY KEY, - code TEXT NOT NULL, - expires_at TEXT NOT NULL - )`, - } - - for _, m := range migrations { - if _, err := db.Exec(m); err != nil { - log.Fatalf("migration: %v", err) - } - } - - log.Println(" database ready") -} - -// Accounts - -func accountGet(email string) (bool, string, error) { - var stripeID string - err := db.QueryRow("SELECT stripe_id FROM accounts WHERE email = ?", email).Scan(&stripeID) - if err == sql.ErrNoRows { - return false, "", nil - } - if err != nil { - return false, "", err - } - return true, stripeID, nil -} - -func accountCreate(email string) error { - _, err := db.Exec("INSERT OR IGNORE INTO accounts (email) VALUES (?)", email) - return err -} - -// Vaults - -func vaultList(email string) ([]Vault, error) { - rows, err := db.Query( - "SELECT vault_id, region, expires_at, created_at FROM vaults WHERE account_email = ? ORDER BY created_at", - email, - ) - if err != nil { - return nil, err - } - defer rows.Close() - - var vaults []Vault - for rows.Next() { - var v Vault - if err := rows.Scan(&v.ID, &v.Region, &v.ExpiresAt, &v.CreatedAt); err != nil { - return nil, err - } - vaults = append(vaults, v) - } - return vaults, nil -} - -func vaultCount(email string) (int, error) { - var n int - err := db.QueryRow("SELECT COUNT(*) FROM vaults WHERE account_email = ?", email).Scan(&n) - return n, err -} - -func vaultCreate(id, email, region string) error { - expires := time.Now().AddDate(1, 0, 0).UTC().Format(time.RFC3339) - _, err := db.Exec( - "INSERT INTO vaults (vault_id, account_email, region, expires_at) VALUES (?, ?, ?, ?)", - id, email, region, expires, - ) - return err -} - -func vaultDelete(id, email string) error { - res, err := db.Exec("DELETE FROM vaults WHERE vault_id = ? AND account_email = ?", id, email) - if err != nil { - return err - } - n, _ := res.RowsAffected() - if n == 0 { - return sql.ErrNoRows - } - return nil -} - -// Sessions - -func sessionCreate(email string) (string, error) { - token := randomToken(32) - expires := time.Now().Add(24 * time.Hour).UTC().Format(time.RFC3339) - _, err := db.Exec( - "INSERT INTO sessions (token, email, expires_at) VALUES (?, ?, ?)", - token, email, expires, - ) - return token, err -} - -func sessionGet(token string) (string, error) { - var email string - var expires string - err := db.QueryRow("SELECT email, expires_at FROM sessions WHERE token = ?", token).Scan(&email, &expires) - if err != nil { - return "", err - } - t, _ := time.Parse(time.RFC3339, expires) - if time.Now().After(t) { - db.Exec("DELETE FROM sessions WHERE token = ?", token) - return "", sql.ErrNoRows - } - return email, nil -} - -func sessionDelete(token string) { - db.Exec("DELETE FROM sessions WHERE token = ?", token) -} - -// Login codes - -func loginCodeSet(email, code string) error { - expires := time.Now().Add(10 * time.Minute).UTC().Format(time.RFC3339) - _, err := db.Exec( - "INSERT OR REPLACE INTO login_codes (email, code, expires_at) VALUES (?, ?, ?)", - email, code, expires, - ) - return err -} - -func loginCodeVerify(email, code string) (bool, error) { - var stored string - var expires string - err := db.QueryRow("SELECT code, expires_at FROM login_codes WHERE email = ?", email).Scan(&stored, &expires) - if err != nil { - return false, nil - } - t, _ := time.Parse(time.RFC3339, expires) - if time.Now().After(t) { - db.Exec("DELETE FROM login_codes WHERE email = ?", email) - return false, nil - } - if stored != code { - return false, nil - } - db.Exec("DELETE FROM login_codes WHERE email = ?", email) - return true, nil -} - -// Types - -type Vault struct { - ID string `json:"vault_id"` - Region string `json:"region"` - ExpiresAt string `json:"expires_at"` - CreatedAt string `json:"created_at"` -} diff --git a/clavitor.com/account/favicon.svg b/clavitor.com/account/favicon.svg deleted file mode 100644 index 92d2303..0000000 --- a/clavitor.com/account/favicon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - v - 84 - diff --git a/clavitor.com/account/go.mod b/clavitor.com/account/go.mod deleted file mode 100644 index 666606c..0000000 --- a/clavitor.com/account/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module clavitor.com/account - -go 1.23.6 - -require github.com/mattn/go-sqlite3 v1.14.37 // indirect diff --git a/clavitor.com/account/go.sum b/clavitor.com/account/go.sum deleted file mode 100644 index 9c79a75..0000000 --- a/clavitor.com/account/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/mattn/go-sqlite3 v1.14.37 h1:3DOZp4cXis1cUIpCfXLtmlGolNLp2VEqhiB/PARNBIg= -github.com/mattn/go-sqlite3 v1.14.37/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= diff --git a/clavitor.com/account/main.go b/clavitor.com/account/main.go deleted file mode 100644 index a62f630..0000000 --- a/clavitor.com/account/main.go +++ /dev/null @@ -1,202 +0,0 @@ -package main - -import ( - "embed" - "html/template" - "io/fs" - "log" - "net/http" - "os" - "path/filepath" - "strings" -) - -//go:embed templates/*.tmpl account.css favicon.svg -var embedded embed.FS - -var devMode bool -var basePath string - -type PageData struct { - Page string - Title string - Desc string - ActiveNav string - Base string - Data any -} - -func main() { - port := os.Getenv("PORT") - if port == "" { - port = "8098" - } - - devMode = os.Getenv("DEV") == "1" - basePath = strings.TrimRight(os.Getenv("BASE_PATH"), "/") - - dbPath := os.Getenv("DB_PATH") - if dbPath == "" { - dbPath = "account.db" - } - initDB(dbPath) - - mux := http.NewServeMux() - - // Pages - mux.HandleFunc("/", handleIndex) - mux.HandleFunc("/login", handleLogin) - mux.HandleFunc("/verify", handleVerify) - mux.HandleFunc("/dashboard", handleDashboard) - mux.HandleFunc("/checkout", handleCheckout) - mux.HandleFunc("/regions", handleRegions) - mux.HandleFunc("/settings", handleSettings) - - // API - mux.HandleFunc("/api/auth/email", apiAuthEmail) - mux.HandleFunc("/api/auth/verify", apiAuthVerify) - mux.HandleFunc("/api/auth/logout", apiAuthLogout) - mux.HandleFunc("/api/checkout", apiCheckout) - mux.HandleFunc("/api/vaults", apiVaults) - mux.HandleFunc("/api/vault/create", apiVaultCreate) - mux.HandleFunc("/api/vault/", apiVaultDelete) // /api/vault/{id}/delete - mux.HandleFunc("/api/account", apiAccount) - - // Static assets - mux.HandleFunc("/account.css", serveStatic("account.css", "text/css")) - mux.HandleFunc("/favicon.svg", serveStatic("favicon.svg", "image/svg+xml")) - - // Strip .html extensions - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if strings.HasSuffix(r.URL.Path, ".html") { - http.Redirect(w, r, strings.TrimSuffix(r.URL.Path, ".html"), http.StatusMovedPermanently) - return - } - mux.ServeHTTP(w, r) - }) - - log.Printf("clavitor account · :%s", port) - if devMode { - log.Println(" dev mode: templates reload from disk") - } - log.Fatal(http.ListenAndServe(":"+port, handler)) -} - -func loadTemplates(page string) (*template.Template, error) { - if devMode { - base := filepath.Join("templates", "base.tmpl") - pg := filepath.Join("templates", page+".tmpl") - return template.ParseFiles(base, pg) - } - return template.ParseFS(embedded, "templates/base.tmpl", "templates/"+page+".tmpl") -} - -func render(w http.ResponseWriter, page string, data PageData) { - data.Base = basePath - tmpl, err := loadTemplates(page) - if err != nil { - log.Printf("template error: %v", err) - http.Error(w, "internal error", 500) - return - } - w.Header().Set("Content-Type", "text/html; charset=utf-8") - if err := tmpl.Execute(w, data); err != nil { - log.Printf("render error: %v", err) - } -} - -func serveStatic(name, contentType string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var data []byte - var err error - if devMode { - data, err = os.ReadFile(name) - } else { - data, err = fs.ReadFile(embedded, name) - } - if err != nil { - http.NotFound(w, r) - return - } - w.Header().Set("Content-Type", contentType) - w.Header().Set("Cache-Control", "public, max-age=3600") - w.Write(data) - } -} - -func handleIndex(w http.ResponseWriter, r *http.Request) { - if r.URL.Path != "/" { - http.NotFound(w, r) - return - } - http.Redirect(w, r, basePath+"/login", http.StatusTemporaryRedirect) -} - -func handleLogin(w http.ResponseWriter, r *http.Request) { - // Already logged in? Go to dashboard - if authEmail(r) != "" { - http.Redirect(w, r, basePath+"/dashboard", http.StatusTemporaryRedirect) - return - } - render(w, "login", PageData{ - Page: "login", - Title: "Sign in — clavitor", - Desc: "Sign in to your clavitor account", - }) -} - -func handleVerify(w http.ResponseWriter, r *http.Request) { - render(w, "verify", PageData{ - Page: "verify", - Title: "Enter code — clavitor", - Desc: "Verify your login code", - Data: r.URL.Query().Get("email"), - }) -} - -func handleDashboard(w http.ResponseWriter, r *http.Request) { - if authEmail(r) == "" { - http.Redirect(w, r, basePath+"/login", http.StatusTemporaryRedirect) - return - } - render(w, "dashboard", PageData{ - Page: "dashboard", - Title: "Dashboard — clavitor", - Desc: "Manage your vaults", - ActiveNav: "dashboard", - }) -} - -func handleCheckout(w http.ResponseWriter, r *http.Request) { - render(w, "checkout", PageData{ - Page: "checkout", - Title: "Get started — clavitor", - Desc: "Create your clavitor account", - }) -} - -func handleRegions(w http.ResponseWriter, r *http.Request) { - if authEmail(r) == "" { - http.Redirect(w, r, basePath+"/login", http.StatusTemporaryRedirect) - return - } - render(w, "regions", PageData{ - Page: "regions", - Title: "Choose your region — clavitor", - Desc: "Pick where your vault lives", - ActiveNav: "dashboard", - }) -} - -func handleSettings(w http.ResponseWriter, r *http.Request) { - if authEmail(r) == "" { - http.Redirect(w, r, basePath+"/login", http.StatusTemporaryRedirect) - return - } - render(w, "settings", PageData{ - Page: "settings", - Title: "Settings — clavitor", - Desc: "Account settings", - ActiveNav: "settings", - }) -} diff --git a/clavitor.com/account/templates/base.tmpl b/clavitor.com/account/templates/base.tmpl deleted file mode 100644 index 96f0e0e..0000000 --- a/clavitor.com/account/templates/base.tmpl +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - {{.Title}} - - - - - - - - - -
-
-
- {{template "page" .}} -
- {{template "scripts" .}} - - diff --git a/clavitor.com/account/templates/checkout.tmpl b/clavitor.com/account/templates/checkout.tmpl deleted file mode 100644 index 546ff9e..0000000 --- a/clavitor.com/account/templates/checkout.tmpl +++ /dev/null @@ -1,107 +0,0 @@ -{{define "page"}} -
-
- Get started -

Your vault awaits

- -
- $12 - /year -
-
- 30-day money-back guarantee. No questions asked. -
- -
- -
    -
  • - - Zero-knowledge encryption — we cannot read your vault -
  • -
  • - - Field-level AI visibility — agents see what you allow -
  • -
  • - - 23 global regions — pick where your data lives -
  • -
  • - - WebAuthn PRF — hardware key is the only key -
  • -
  • - - FIPS 140-3 certified cryptography -
  • -
  • - - MCP, CLI, browser extension, REST API -
  • -
- -
- -
-
- - -
- -
- - - -
- - Payments processed by Stripe. Cancel anytime. - -
-
-
-{{end}} - -{{define "scripts"}} - -{{end}} diff --git a/clavitor.com/account/templates/dashboard.tmpl b/clavitor.com/account/templates/dashboard.tmpl deleted file mode 100644 index 784e3c5..0000000 --- a/clavitor.com/account/templates/dashboard.tmpl +++ /dev/null @@ -1,165 +0,0 @@ -{{define "page"}} -
- -
- -
-
-
-
- Account -

Your vaults

-
- - - New vault - -
-
- - -
-
-
- Loading… -
-
-
- - -
-
-
- Plan -
Consumer
-
$12/year
-
- Manage billing -
-
- - -
-
-
-
-
-
Vaults
-
-
-
-
-
Days left
-
-
-
-
-
Regions
-
-
-
-
-{{end}} - -{{define "scripts"}} - -{{end}} diff --git a/clavitor.com/account/templates/login.tmpl b/clavitor.com/account/templates/login.tmpl deleted file mode 100644 index 3c982ff..0000000 --- a/clavitor.com/account/templates/login.tmpl +++ /dev/null @@ -1,99 +0,0 @@ -{{define "page"}} - -{{end}} - -{{define "scripts"}} - -{{end}} diff --git a/clavitor.com/account/templates/regions.tmpl b/clavitor.com/account/templates/regions.tmpl deleted file mode 100644 index f1bbc4d..0000000 --- a/clavitor.com/account/templates/regions.tmpl +++ /dev/null @@ -1,263 +0,0 @@ -{{define "page"}} -
-
- -
-
- -
-
- New vault -

Choose your region

-

- Your vault lives in one region. All data stays there. Pick the closest location for the best performance. -

-
- -
-
Headquarters
-
-
- 🇨🇭 - Zürich - Switzerland - HQ · Swiss jurisdiction -
-
-
- -
-
Americas
-
-
- 🇺🇸 - Virginia - US East -
-
- 🇺🇸 - San Francisco - US West -
-
- 🇨🇦 - Montréal - Canada -
-
- 🇲🇽 - Mexico City - Mexico -
-
- 🇨🇴 - Bogotá - Colombia -
-
- 🇧🇷 - São Paulo - Brazil -
-
- 🇨🇱 - Santiago - Chile -
-
- 🇦🇷 - Buenos Aires - Argentina -
-
-
- -
-
Europe
-
-
- 🇬🇧 - London - United Kingdom -
-
- 🇪🇸 - Madrid - Spain -
-
-
- -
-
Middle East & Africa
-
-
- 🇹🇷 - Istanbul - Turkey -
-
- 🇦🇪 - Dubai - UAE -
-
- 🇿🇦 - Cape Town - South Africa -
-
-
- -
-
Asia Pacific
-
-
- 🇮🇳 - Mumbai - India -
-
- 🇸🇬 - Singapore - Singapore -
-
- 🇭🇰 - Hong Kong - China -
-
- 🇰🇷 - Seoul - South Korea -
-
- 🇯🇵 - Tokyo - Japan -
-
- 🇦🇺 - Sydney - Australia -
-
- 🇰🇿 - Almaty - Kazakhstan -
-
-
- - -
-
-
-
- - -
- -
-
-
-
-{{end}} - -{{define "scripts"}} - -{{end}} diff --git a/clavitor.com/account/templates/settings.tmpl b/clavitor.com/account/templates/settings.tmpl deleted file mode 100644 index e0b5f70..0000000 --- a/clavitor.com/account/templates/settings.tmpl +++ /dev/null @@ -1,179 +0,0 @@ -{{define "page"}} -
- -
- -
-
- Account -

Settings

-
- -
- -
-
-
-
Email
-
johan@example.com
-
-
-
- - -
-
-
-
Authentication
-
- Passkey registered · - Active -
-
- -
-
- - -
-
-
-
Billing
-
- $12/year · Next charge Mar 20, 2027 -
-
- -
-
- - -
-
-
-
Invoices
-
View and download past invoices
-
- -
-
-
- - -
-
-

Danger zone

-

- Deleting your account cancels your subscription, deletes all vaults, - and removes all data. This cannot be undone. -

- -
-
-
-{{end}} - -{{define "scripts"}} - -{{end}} diff --git a/clavitor.com/account/templates/verify.tmpl b/clavitor.com/account/templates/verify.tmpl deleted file mode 100644 index 8799877..0000000 --- a/clavitor.com/account/templates/verify.tmpl +++ /dev/null @@ -1,73 +0,0 @@ -{{define "page"}} - -{{end}} - -{{define "scripts"}} - -{{end}} diff --git a/clavitor.com/clavitor-web-linux-amd64 b/clavitor.com/clavitor-web-linux-amd64 index 3047ed5..6d3487d 100755 Binary files a/clavitor.com/clavitor-web-linux-amd64 and b/clavitor.com/clavitor-web-linux-amd64 differ diff --git a/clavitor.com/clavitor.css b/clavitor.com/clavitor.css index 28ab734..ac8dff8 100644 --- a/clavitor.com/clavitor.css +++ b/clavitor.com/clavitor.css @@ -144,6 +144,12 @@ code { font-size: 0.875em; } .grid-3-equal { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; } .grid-4-equal { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; } +/* === TABLES === */ +.data-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; } +.data-table th { text-align: left; font-weight: 600; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-tertiary); padding: 8px 12px; border-bottom: 2px solid var(--border); } +.data-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); color: var(--text); } +.data-table tr:last-child td { border-bottom: none; } + /* === CODE BLOCKS === */ .code-block { background: var(--bg-inverse); border-radius: var(--radius); padding: 1.5rem; font-family: var(--font-mono); font-size: 0.875rem; overflow-x: auto; line-height: 1.7; color: #d1d5db; } .code-block .prompt { color: #fca5a5; } diff --git a/clavitor.com/clavitor.db-shm b/clavitor.com/clavitor.db-shm index ac8ad67..b2e57b4 100644 Binary files a/clavitor.com/clavitor.db-shm and b/clavitor.com/clavitor.db-shm differ diff --git a/clavitor.com/clavitor.db-wal b/clavitor.com/clavitor.db-wal index 8be596c..7d03472 100644 Binary files a/clavitor.com/clavitor.db-wal and b/clavitor.com/clavitor.db-wal differ diff --git a/clavitor.com/tailwind.min.css b/clavitor.com/tailwind.min.css deleted file mode 100644 index 4be7d66..0000000 --- a/clavitor.com/tailwind.min.css +++ /dev/null @@ -1 +0,0 @@ -*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:JetBrains Mono,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.-top-3{top:-.75rem}.right-6{right:1.5rem}.top-0{top:0}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-14{margin-bottom:3.5rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-12{margin-left:3rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-6xl{max-width:72rem}.max-w-7xl{max-width:80rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-shrink-0{flex-shrink:0}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.columns-1{-moz-columns:1;column-count:1}.break-inside-avoid{-moz-column-break-inside:avoid;break-inside:avoid}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1\.5{gap:.375rem}.gap-16{gap:4rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2.5rem*var(--tw-space-y-reverse));margin-top:calc(2.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-12>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(3rem*var(--tw-space-y-reverse));margin-top:calc(3rem*(1 - var(--tw-space-y-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-accent\/30{border-color:rgba(34,197,94,.3)}.border-danger\/30{border-color:rgba(239,68,68,.3)}.border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity,1))}.border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}.border-green-500\/20{border-color:rgba(34,197,94,.2)}.border-red-500\/10{border-color:rgba(239,68,68,.1)}.border-red-500\/20{border-color:rgba(239,68,68,.2)}.border-white\/5{border-color:hsla(0,0%,100%,.05)}.border-yellow-600\/30{border-color:rgba(202,138,4,.3)}.bg-accent{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity,1))}.bg-accent\/10{background-color:rgba(34,197,94,.1)}.bg-accent\/5{background-color:rgba(34,197,94,.05)}.bg-danger\/10{background-color:rgba(239,68,68,.1)}.bg-danger\/5{background-color:rgba(239,68,68,.05)}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity,1))}.bg-green-500\/5{background-color:rgba(34,197,94,.05)}.bg-navy{--tw-bg-opacity:1;background-color:rgb(10 22 40/var(--tw-bg-opacity,1))}.bg-navy-light{--tw-bg-opacity:1;background-color:rgb(17 31 56/var(--tw-bg-opacity,1))}.bg-navy-light\/50{background-color:rgba(17,31,56,.5)}.bg-navy\/80{background-color:rgba(10,22,40,.8)}.bg-navy\/95{background-color:rgba(10,22,40,.95)}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-1\.5{padding-bottom:.375rem;padding-top:.375rem}.py-12{padding-bottom:3rem;padding-top:3rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-20{padding-bottom:5rem;padding-top:5rem}.py-24{padding-bottom:6rem;padding-top:6rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-4{padding-bottom:1rem;padding-top:1rem}.pb-12{padding-bottom:3rem}.pb-20{padding-bottom:5rem}.pt-12{padding-top:3rem}.pt-32{padding-top:8rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:JetBrains Mono,monospace}.font-sans{font-family:Inter,system-ui,sans-serif}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-accent{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.text-danger{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-green-400{--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-75{opacity:.75}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.hover\:border-accent:hover{--tw-border-opacity:1;border-color:rgb(34 197 94/var(--tw-border-opacity,1))}.hover\:border-gray-400:hover{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity,1))}.hover\:bg-accent-hover:hover{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity,1))}.hover\:text-accent:hover{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.hover\:text-gray-300:hover{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.hover\:text-gray-400:hover{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}@media (min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:768px){.md\:flex{display:flex}.md\:hidden{display:none}.md\:columns-2{-moz-columns:2;column-count:2}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-5xl{font-size:3rem;line-height:1}}@media (min-width:1024px){.lg\:columns-3{-moz-columns:3;column-count:3}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:text-\[3\.25rem\]{font-size:3.25rem}} \ No newline at end of file diff --git a/clavitor.com/templates/hosted.tmpl b/clavitor.com/templates/hosted.tmpl index 41419fb..6c9c800 100644 --- a/clavitor.com/templates/hosted.tmpl +++ b/clavitor.com/templates/hosted.tmpl @@ -14,6 +14,10 @@ CLAVITOR GLOBAL PRESENCE +
+

We have strategically chosen our datacenter locations so that almost every place on the planet gets an answer within 60 ms. If your location is slower than that, reach out and we will work on a solution.

+ +
@@ -102,6 +106,28 @@
+ +
+

Disaster recovery

+

Your backup is on the other side of the world.

+

Every vault is automatically replicated to an inland backup location — no coastline, no tsunami risk, no storm surge. The two backup sites are Calgary and Zürich: different continents, different jurisdictions, maximum geographic separation. Your data is encrypted end-to-end — nobody but you can read it.

+ + + + + + {{range .Pops}}{{if eq .Status "live"}} + {{if eq .City "Zürich"}} + {{else if eq .City "Calgary"}} + {{else if or (eq .Country "JP") (eq .Country "KR") (eq .Country "AU") (eq .Country "SG") (eq .Country "IN") (eq .Country "HK") (eq .Country "ZA") (eq .Country "NG") (eq .Country "SE")}} + {{else}} + {{end}}{{end}}{{end}} + +
Your regionBackup locationWhy
{{.City}}Calgary, CanadaOpposite continent, inland
{{.City}}Zürich, SwitzerlandOpposite continent, inland
{{.City}}Calgary, CanadaFarthest inland site
{{.City}}Zürich, SwitzerlandFarthest inland site
+
+ +
+

Ready?

@@ -234,7 +260,7 @@ } const POPS = [{{range .Pops}} - {city:"{{.City}}", region:"{{.RegionName}}", lat:{{.Lat}}, lon:{{.Lon}}, status:"{{.Status}}", provider:"{{.Provider}}"},{{end}} + {city:"{{.City}}", country:"{{.Country}}", region:"{{.RegionName}}", lat:{{.Lat}}, lon:{{.Lon}}, status:"{{.Status}}", provider:"{{.Provider}}"},{{end}} ]; // Render all POP dots from DB data @@ -243,6 +269,45 @@ POPS.forEach((pop, i) => addPopDot(svg, pop, (i * 0.08).toFixed(2))); } + // Backup route lines + const backupToCalgary = new Set(['JP','KR','AU','SG','IN','HK','ZA','NG','SE']); + function getBackupCity(pop) { + if (pop.city === 'Zürich') return 'Calgary'; + if (pop.city === 'Calgary') return 'Zürich'; + return backupToCalgary.has(pop.country) ? 'Calgary' : 'Zürich'; + } + + let backupLines = []; + let backupVisible = false; + const backupBtn = document.getElementById('backup-toggle'); + if (backupBtn) { + backupBtn.addEventListener('click', function() { + backupVisible = !backupVisible; + if (backupVisible) { + backupBtn.textContent = 'Hide backup routes'; + const livePops = POPS.filter(p => p.status === 'live'); + livePops.forEach(pop => { + const backupCity = getBackupCity(pop); + const target = livePops.find(p => p.city === backupCity); + if (!target || target.city === pop.city) return; + const [x1, y1] = project(pop.lon, pop.lat); + const [x2, y2] = project(target.lon, target.lat); + const line = document.createElementNS(ns, 'line'); + line.setAttribute('x1', x1); line.setAttribute('y1', y1); + line.setAttribute('x2', x2); line.setAttribute('y2', y2); + line.setAttribute('stroke', '#DC2626'); line.setAttribute('stroke-width', '0.8'); + line.setAttribute('stroke-opacity', '0.3'); line.setAttribute('stroke-dasharray', '4 3'); + svg.insertBefore(line, svg.querySelector('rect')); + backupLines.push(line); + }); + } else { + backupBtn.textContent = 'Show backup routes'; + backupLines.forEach(l => l.remove()); + backupLines = []; + } + }); + } + function findClosestPop(lat, lon) { return POPS.reduce((best, p) => { const d = (lat-p.lat)**2 + (lon-p.lon)**2; diff --git a/clavitor.com/templates/index-v2.tmpl b/clavitor.com/templates/index-v2.tmpl deleted file mode 100644 index 8acebf0..0000000 --- a/clavitor.com/templates/index-v2.tmpl +++ /dev/null @@ -1,509 +0,0 @@ -{{define "index"}} - -
-
-

George Orwell — 1984

-

"If you want to keep a secret, you must also hide it from yourself."

-

The only password manager for AI agents worth your trust.

-

We cannot read your passwords. Not will not. Cannot. Your Credential and Identity keys are derived from your hardware authenticator and baked into your tokens. Our servers hold ciphertext they have never had the means to decrypt.

- -
-
- - - - - - - AI Agent - You only - - - - - - - - - - - - - Credential Encryption - - - - - github_token - - - - - - ssh_key - - - - - - totp_github - - - - - - oauth_slack - - - - - - - - Identity Encryption - - - - - credit_card - - - - - - cvv - - - - - - passport - - - - - - ssn - - - - - - - - - -
-
- -
- - -
-

The problem with every other password manager

-

In 2022, attackers stole the entire vault database of a leading password manager. The encryption worked exactly as designed. Accounts are still being drained today — four years later. The problem was never the encryption. It was who held the key.

-
-
-
-

They hold the key

-

Every major password manager encrypts your vault — then stores a way to decrypt it. The company's servers have always had what it takes to read your passwords. You just hoped they wouldn't.

-
-
-
-

Policy isn't protection

-

"We will not read your passwords" is a promise. Promises can be broken, compelled, or hacked. Clavitor cannot read your Credential or Identity fields — not will not. Cannot. The key was never here.

-
-
-
-

AI agents need credentials now

-

Your AI needs your GitHub token to deploy. It shouldn't also be able to see your passport. Every other manager is all-or-nothing. Clavitor gives agents exactly what they need — nothing more.

-
-
-
- -
- - -
-

How it works

-

"Your assistant can book your flights.
Not read your diary."

-

Everything in your vault is encrypted. What differs is who holds the key.

-

Vault Encryption covers everything — the server uses it to store and serve your data. Credential and Identity fields go further: those keys are derived from your hardware authenticator, baked into your tokens, and never sent to our servers. We hold the vault. We never got those keys.

-
-
- Vault Encryption -

Titles, URLs, usernames

-

Server-readable. Encrypted at rest with the vault key. Needed for search, entry listing, and MCP tool responses.

-
    -
  • Entry names & labels
  • -
  • URLs
  • -
  • Usernames
  • -
  • Tags & metadata
  • -
-
-
- Credential Encryption -

AI-readable secrets

-

Encrypted client-side. The key lives in your agent tokens. The server stores ciphertext it has never had the means to decrypt.

-
    -
  • API keys & tokens
  • -
  • SSH keys
  • -
  • TOTP 2FA seeds — AI generates codes
  • -
  • OAuth tokens
  • -
-
-
- Identity Encryption -

Your device only

-

Encrypted client-side with a key derived from your WebAuthn PRF. Hardware tap required. Not in tokens. Agents receive [Identity Encryption — hardware key required].

-
    -
  • Credit card numbers & CVV
  • -
  • Passport & government IDs
  • -
  • Social security numbers
  • -
  • Seed phrases & private keys
  • -
-
-
-
- -
- - -
-

Built different

-

Not another password manager with an AI checkbox. The architecture is the feature.

-
-
-
-

Field-level encryption tiers

-

Each field carries its own encryption layer. Your AI reads the API key, not the CVV. Same entry, different keys, different access.

-
-
-
-

WebAuthn PRF

-

Credential and Identity keys derive from your WebAuthn authenticator hardware — Touch ID, Face ID, YubiKey, Titan Key. No master password. No server-side key storage. Math, not policy.

-
-
-
-

AI-powered 2FA

-

Store TOTP secrets as Credential fields. Your AI generates time-based codes on demand via MCP — no more switching to your phone during a deployment.

-
-
-
-

Client-side encryption

-

Your browser and agents encrypt before anything leaves the client. The vault stores what it receives. It has never seen your Credential or Identity plaintext.

-
-
-
-

One binary, one file

-

No Docker. No Postgres. No Redis. One Go binary, one SQLite file. Runs on a Raspberry Pi. Runs on a $4/month VPS. Port 1984.

-
-
-
-

Smart import

-

Native parsers for Chrome, Firefox, Bitwarden, Proton Pass. Any other format via LLM. Auto-detects which fields should be Credential vs Identity. Collision resolution by modification date.

-
-
-
- -
- - -
-
-
-

Your agents get in.
Nobody else gets anything.

-

MCP-native from day one. Every AI agent that supports MCP can read credentials, fetch API keys, and generate 2FA codes — using only what it needs.

-

Each token is a combined credential: MCP auth and the Credential private key, wrapped together. The agent decrypts locally. The server sees a request and returns ciphertext. Nothing in between.

-
-

~/.claude/mcp.json

-
{
-  "mcpServers": {
-    "clavitor": {
-      "url": "http://localhost:1984/mcp",
-      "headers": {
-        "Authorization": "Bearer v1984_..."
-      }
-    }
-  }
-}
-
-
-
-
-

MCP Tools

-
    -
  • get_credential — fetch by query
  • -
  • list_credentials — list accessible entries
  • -
  • get_totp — live 2FA code
  • -
  • search_vault — full-text search
  • -
  • check_expiring — upcoming expirations
  • -
  • save_credential — write (explicit permission only)
  • -
-
-
-

Identity Encryption fields

-

Agents receive [Identity Encryption — hardware key required] for card numbers, passports, and government IDs. They know the field exists. They cannot read it. Ever.

-
-
-
-
- -
- - -
-

Your agent and you — same vault, right access

-

Four ways in. Each designed for a different context. All pointing at the same encrypted store.

-
-
-

MCP

-

For AI agents

-

Claude Code, Codex, Cursor, or any MCP-compatible agent. Search credentials, fetch API keys, complete 2FA flows — without asking you.

-
-
-

Extension

-

For humans in a browser

-

Autofill passwords, generate 2FA codes inline. LLM field mapping fills by intent, not CSS selector — works on SPAs, obfuscated forms, multi-step flows.

-
-
-

CLI

-

For terminal workflows

-

Pipe credentials into scripts and CI pipelines. vault get github.token — done.

-
-
-

API

-

For everything else

-

REST API with read/write tokens. Full audit log: every access tagged by actor — web, extension, MCP, or agent name.

-
-
-
- -
- - -
-

Real complaints. Real users.

-

We listened. And addressed them all.

-

Verbatim quotes from real users — pulled from public forums, GitHub issues, and community threads. Not cherry-picked. Not paraphrased.

- -
- -
-

Leading password manager — Community Forum

-

"The web extensions are laughably bad at this point. This has been going on for months. They either won't fill, wont' unlock, or just plain won't do anything (even clicking extension icon). It's so bad"

-

Community forum, April 2024

-
-
    -
  • clavitor: No desktop app dependency. The extension calls the vault binary directly — no IPC, no sync layer, no unlock chain.
  • -
-
- -
-

Leading password manager — GitHub Issues

-

"Every single website loads slower. From Google, up to social media websites like Reddit, Instagram, X... Even scrolling and animation stutters sometimes. So for me the browser extension is unusable. It interferes with my browsing experience like malware."

-

GitHub Issues, 2024

-
-
    -
  • clavitor: Zero content scripts. The extension injects nothing into pages — fills via browser autofill API, on demand, when you ask.
  • -
-
- -
-

Leading password manager — Hacker News

-

"The fact they're drip-feeding how bad this breach actually was is terrible enough... Personally I'm never touching them again."

-

Hacker News, January 2023

-
-
    -
  • clavitor: Credential and Identity fields are encrypted before they reach us. We mathematically cannot read them — and neither can anyone who breaches our servers.
  • -
-
- -
-

Leading password manager — Community Forum

-

"Since doing so, it asks me to enter my password every 10 minutes or so in the chrome extension"

-

Community forum, November 2022

-
-
    -
  • clavitor: WebAuthn-first. Your authenticator is the primary unlock. Session lives locally — no server-side token expiry forcing re-auth every few minutes.
  • -
-
- -
-

Leading password manager — Community Forums

-

"the password not only auto-filled in the password field, but also auto-filled in reddit's search box!"

-

Community forum

-
-
    -
  • clavitor: LLM field mapping. The extension reads the form and asks the model which field is which — fills by intent, not by CSS selector guesswork.
  • -
-
- -
-

Leading password manager — Community Forums

-

"Bitwarden REFUSES to autofill the actual password saved for a given site or app...and instead fills an old password. It simply substitutes the OLD password for the new one that is plainly saved in the vault."

-

Community forum

-
-
    -
  • clavitor: LLM field mapping matches by intent. Entries are indexed by URL — the right credential, every time.
  • -
-
- -
- -

All quotes verbatim from public posts. View sources →

-
- -
- - -
-

Your vault needs to be everywhere you are.

-

A password manager that only works on your home network isn't a password manager. Your laptop moves. Your phone moves. Your agents run on servers in three time zones.

-

Self-hosting means a server with a public IP, DNS, TLS certificates, uptime monitoring, and backups. That's not a weekend project — that's infrastructure.

-

We run clavitor across regions on every continent. $20 $12/yr. Your Credential and Identity keys never leave your browser — we cannot read your private fields. Not policy. Math.

- -
- -
- - -
-

Up and running in 30 seconds

-

One command. No dependencies.

-
-

Terminal

-
# Self-host in 30 seconds
-
$ curl -fsSL clavitor.com/install.sh | sh
-
$ clavitor
-
# Running on http://localhost:1984
-
-
-

MCP config for Claude Code / Cursor / Codex

-
{
-  "mcpServers": {
-    "clavitor": {
-      "url": "http://localhost:1984/mcp",
-      "headers": { "Authorization": "Bearer v1984_your_token_here" }
-    }
-  }
-}
-
-

Full install guide →

-
-{{end}} - -{{define "index-script"}} - -{{end}} diff --git a/clavitor.com/templates/styleguide.css b/clavitor.com/templates/styleguide.css deleted file mode 100644 index 5340f8f..0000000 --- a/clavitor.com/templates/styleguide.css +++ /dev/null @@ -1,340 +0,0 @@ -/* ============================================ - CLAVITOR DESIGN SYSTEM — v0.1 - Violet #7C3AED + Figtree + JetBrains Mono - ============================================ */ - -:root { - /* Brand */ - --brand-black: #0A0A0A; - --brand-accent: #7C3AED; - --brand-accent-light: #8B5CF6; - --brand-accent-dark: #6D28D9; - - /* Core Colors */ - --bg-primary: #FFFFFF; - --bg-secondary: #F5F5F5; - --bg-tertiary: #E5E5E5; - --bg-inverse: #0A0A0A; - - --text-primary: #171717; - --text-secondary: #525252; - --text-tertiary: #737373; - --text-inverse: #FFFFFF; - - --border-default: #E5E5E5; - --border-strong: #D4D4D4; - - /* Semantic */ - --success: #16A34A; - --warning: #CA8A04; - --error: #DC2626; - - /* Typography */ - --font-family: "Figtree", system-ui, sans-serif; - - /* Wordmark */ - --wordmark-font: "Figtree", system-ui, sans-serif; - --wordmark-weight: 700; - --wordmark-spacing: 0.25em; - - /* Spacing */ - --space-1: 4px; - --space-2: 8px; - --space-3: 12px; - --space-4: 16px; - --space-5: 20px; - --space-6: 24px; - --space-8: 32px; - --space-10: 40px; - --space-12: 48px; - --space-16: 64px; - - /* Motion */ - --duration-fast: 100ms; - --ease-default: cubic-bezier(0.4, 0, 0.2, 1); -} - -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } - -html { - font-family: var(--font-family); - font-size: 16px; - line-height: 1.5; - color: var(--text-primary); - background: var(--bg-primary); - -webkit-font-smoothing: antialiased; -} - -/* ============================================ - LAYOUT - ============================================ */ - -.container { max-width: 1200px; margin: 0 auto; padding: 48px 24px; } -.section { margin-bottom: 64px; } -.max-width { max-width: 1200px; margin: 0 auto; padding: 0 24px; } - -/* Grid */ -.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; } -.grid-2-equal { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; overflow: visible; } -.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; } -.grid-3-equal { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; } -.grid-4-equal { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; } -.grid-6 { display: grid; grid-template-columns: repeat(6, 1fr); gap: 16px; } - -/* Flex */ -.flex-row { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; } -.flex-col { display: flex; flex-direction: column; gap: 12px; } - -/* ============================================ - TYPOGRAPHY - ============================================ */ - -h1 { font-size: 72px; font-weight: 700; letter-spacing: -0.022em; line-height: 1; } -h2 { font-size: 56px; font-weight: 600; letter-spacing: -0.022em; line-height: 1.1; } -h3 { font-size: 40px; font-weight: 600; letter-spacing: -0.019em; } -h4 { font-size: 28px; font-weight: 500; } - -.text-sm { font-size: 16px; } -.text-xs { font-size: 14px; } -.text-lg { font-size: 18px; } -.text-secondary { color: var(--text-secondary); } -.text-tertiary { color: var(--text-tertiary); } -.text-inverse { color: var(--text-inverse); } -.text-center { text-align: center; } -.text-left { text-align: left; } -.text-right { text-align: right; } - -.font-semibold { font-weight: 600; } -.font-mono { font-family: "JetBrains Mono", monospace; } - -/* Wordmark */ -.wordmark { font-size: 18px; font-weight: var(--wordmark-weight); letter-spacing: var(--wordmark-spacing); text-transform: uppercase; } -.wordmark-lg { font-size: 32px; font-weight: var(--wordmark-weight); letter-spacing: var(--wordmark-spacing); text-transform: uppercase; color: var(--brand-accent); } - -/* ============================================ - BRAND ELEMENTS - ============================================ */ - -.brand-block { display: flex; align-items: center; gap: 16px; margin: 32px 0; } -.black-square { width: 64px; height: 64px; background: var(--brand-black); } -.black-square-sm { width: 48px; height: 48px; background: var(--brand-black); } - -/* Logo Lockup — The Trinity */ -.logo-lockup { display: inline-flex; gap: 20px; align-items: stretch; } -.logo-lockup-square { width: 80px; height: 80px; background: var(--brand-black); flex-shrink: 0; } -.logo-lockup-text { display: flex; flex-direction: column; justify-content: space-between; height: 80px; } -.logo-lockup-wordmark { font-family: var(--font-family); font-size: 56px; font-weight: var(--wordmark-weight); letter-spacing: var(--wordmark-spacing); text-transform: uppercase; color: var(--brand-accent); line-height: 1; } -.logo-lockup-tagline { font-size: 16px; font-weight: 500; color: var(--text-tertiary); letter-spacing: 0.22em; text-transform: uppercase; line-height: 1; margin-bottom: -2px; } - -/* ============================================ - NAVIGATION (New) - ============================================ */ - -.nav { display: flex; align-items: center; justify-content: space-between; padding: 24px 0; border-bottom: 1px solid var(--border-default); } -.nav-links { display: flex; gap: 32px; align-items: center; } -.nav-links a { color: var(--text-secondary); text-decoration: none; font-size: 14px; font-weight: 500; transition: color 100ms ease; } -.nav-links a:hover { color: var(--text-primary); } - -/* ============================================ - SECTION PATTERNS (vault1984 style) - ============================================ */ - -.section-vault { padding: 80px 0; } -.section-vault-dark { padding: 80px 0; background: var(--bg-inverse); color: var(--text-inverse); } - -/* ============================================ - HERO (New) - ============================================ */ - -.hero { padding: 80px 0; } -.hero-content { max-width: 600px; } - -/* ============================================ - COMPONENTS - ============================================ */ - -/* Pills */ -.pill-row { display: flex; flex-wrap: wrap; gap: 12px; overflow: visible; } -.pill { - display: inline-flex; align-items: center; - height: 32px; padding: 0 16px; - white-space: nowrap; - background: var(--bg-secondary); - border: 1px solid var(--border-default); - border-radius: 9999px; - font-size: 14px; font-weight: 500; -} -.pill-accent { background: var(--brand-accent); color: white; border-color: var(--brand-accent); } - -/* Feature Cards */ -.feature-card { background: var(--bg-secondary); border-radius: 12px; padding: 32px; } -.feature-card-dark { background: var(--bg-inverse); color: var(--text-inverse); border-radius: 12px; padding: 32px; } - -/* Stats */ -.stat-number { font-size: 72px; font-weight: 700; color: var(--brand-accent); line-height: 1; margin-bottom: 8px; } -.stat-label { font-size: 14px; color: var(--text-secondary); } - -/* Section Title */ -.section-title { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-tertiary); margin-bottom: 24px; padding-bottom: 12px; border-bottom: 1px solid var(--border-default); } - -/* Buttons */ -.btn { - display: inline-flex; align-items: center; justify-content: center; gap: 8px; - font-family: inherit; font-size: 16px; font-weight: 500; - text-decoration: none; border: none; border-radius: 8px; - cursor: pointer; transition: all 100ms ease; - height: 40px; padding: 0 16px; -} -.btn:focus { outline: none; box-shadow: 0 0 0 2px white, 0 0 0 4px var(--brand-accent); } -.btn-primary { background: var(--brand-black); color: white; } -.btn-primary:hover { background: #262626; } -.btn-secondary { background: transparent; color: var(--text-primary); border: 1px solid var(--border-strong); } -.btn-secondary:hover { background: var(--bg-secondary); } -.btn-accent { background: var(--brand-accent); color: white; } -.btn-accent:hover { background: var(--brand-accent-light); } -.btn-ghost { background: transparent; color: var(--text-primary); } -.btn-ghost:hover { background: var(--bg-secondary); } -.btn-sm { height: 32px; padding: 0 12px; font-size: 14px; } -.btn-lg { height: 48px; padding: 0 20px; } -.btn:disabled { opacity: 0.5; cursor: not-allowed; } - -/* Inputs */ -.input-group { display: flex; flex-direction: column; gap: 8px; } -.input-label { font-size: 14px; font-weight: 500; color: var(--text-primary); } -.input { - height: 40px; padding: 0 12px; - font-family: inherit; font-size: 16px; - color: var(--text-primary); background: var(--bg-primary); - border: 1px solid var(--border-strong); border-radius: 8px; - transition: all 100ms ease; -} -.input:hover { border-color: var(--text-tertiary); } -.input:focus { outline: none; border-color: var(--brand-accent); box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1); } -.input::placeholder { color: var(--text-tertiary); } -.input-error { border-color: var(--error); } -.input-hint { font-size: 12px; color: var(--text-tertiary); } -.input-error-text { font-size: 12px; color: var(--error); } - -/* Cards */ -.card { background: var(--bg-secondary); border-radius: 12px; padding: 24px; } -.card-flat { background: var(--bg-secondary); border: 1px solid var(--border-default); } -.card-header { margin-bottom: 16px; } -.card-title { font-size: 18px; font-weight: 600; } - -/* Badges */ -.badge { display: inline-flex; align-items: center; height: 24px; padding: 0 12px; font-size: 12px; font-weight: 500; border-radius: 8px; } -.badge-default { background: var(--bg-tertiary); color: var(--text-secondary); } -.badge-primary { background: var(--brand-black); color: white; } -.badge-accent { background: var(--brand-accent); color: white; } -.badge-success { background: rgba(22, 163, 74, 0.1); color: var(--success); } -.badge-warning { background: rgba(202, 138, 4, 0.1); color: var(--warning); } -.badge-error { background: rgba(220, 38, 38, 0.1); color: var(--error); } - -/* Alerts */ -.alert { display: flex; gap: 12px; padding: 16px; border-radius: 12px; } -.alert-accent { background: rgba(124, 58, 237, 0.05); } -.alert-success { background: rgba(22, 163, 74, 0.05); } -.alert-error { background: rgba(220, 38, 38, 0.05); } - -/* Tables */ -.table { width: 100%; border-collapse: collapse; font-size: 14px; } -.table th { text-align: left; padding: 12px 16px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-tertiary); background: var(--bg-secondary); border-bottom: 1px solid var(--border-default); } -.table td { padding: 12px 16px; border-bottom: 1px solid var(--border-default); } -.table tr:hover td { background: var(--bg-secondary); } - -/* Code */ -.code-block { background: var(--bg-inverse); color: var(--text-inverse); font-family: "JetBrains Mono", monospace; font-size: 14px; line-height: 1.6; padding: 16px; border-radius: 12px; overflow-x: auto; } - -/* Colors utility */ -.color-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 16px; } -.color-swatch { border-radius: 8px; overflow: hidden; border: 1px solid var(--border-default); } -.color-block { height: 80px; } -.color-label { padding: 12px; font-size: 12px; background: var(--bg-primary); } -.color-label code { font-family: "JetBrains Mono", monospace; background: var(--bg-secondary); padding: 2px 4px; border-radius: 4px; } - -/* ============================================ - UTILITY CLASSES - ============================================ */ - -/* Spacing (margin-top) */ -.mt-0 { margin-top: 0; } -.mt-1 { margin-top: 4px; } -.mt-2 { margin-top: 8px; } -.mt-3 { margin-top: 12px; } -.mt-4 { margin-top: 16px; } -.mt-5 { margin-top: 20px; } -.mt-6 { margin-top: 24px; } -.mt-8 { margin-top: 32px; } -.mt-10 { margin-top: 40px; } -.mt-12 { margin-top: 48px; } -.mt-16 { margin-top: 64px; } - -.mb-0 { margin-bottom: 0; } -.mb-1 { margin-bottom: 4px; } -.mb-2 { margin-bottom: 8px; } -.mb-3 { margin-bottom: 12px; } -.mb-4 { margin-bottom: 16px; } -.mb-5 { margin-bottom: 20px; } -.mb-6 { margin-bottom: 24px; } -.mb-8 { margin-bottom: 32px; } -.mb-10 { margin-bottom: 40px; } -.mb-12 { margin-bottom: 48px; } -.mb-16 { margin-bottom: 64px; } - -/* Auto margins */ -.mx-auto { margin-left: auto; margin-right: auto; } -.ml-auto { margin-left: auto; } -.mr-auto { margin-right: auto; } - -/* Flex/alignment */ -.justify-center { justify-content: center; } -.justify-between { justify-content: space-between; } -.justify-end { justify-content: flex-end; } -.items-center { align-items: center; } -.items-start { align-items: flex-start; } -.items-end { align-items: flex-end; } - -/* Border utilities */ -.border-top { border-top: 1px solid var(--border-default); } -.border-bottom { border-bottom: 1px solid var(--border-default); } -.border-left { border-left: 1px solid var(--border-default); } -.border-right { border-right: 1px solid var(--border-default); } - -/* Width/height */ -.w-full { width: 100%; } -.h-full { height: 100%; } - -/* Max-width */ -.max-w-prose { max-width: 65ch; } -.max-w-md { max-width: 600px; } - -/* ============================================ - RESPONSIVE BREAKPOINTS - ============================================ */ - -@media (max-width: 768px) { - h1 { font-size: 48px; } - h2 { font-size: 36px; } - h3 { font-size: 28px; } - - .grid-2-equal { grid-template-columns: 1fr; gap: 32px; } - .grid-3-equal { grid-template-columns: 1fr; gap: 24px; } - .grid-4-equal { grid-template-columns: repeat(2, 1fr); gap: 24px; } - - .nav { flex-direction: column; gap: 16px; align-items: flex-start; } - .nav-links { flex-wrap: wrap; gap: 16px; } - - .hero { padding: 48px 0; } - .section-vault { padding: 48px 0; } -} - -@media (max-width: 480px) { - h1 { font-size: 36px; } - h2 { font-size: 28px; } - - .grid-4-equal { grid-template-columns: 1fr; } - .pill-row { gap: 8px; } - .pill { padding: 0 12px; font-size: 13px; } - - .btn-lg { height: 44px; padding: 0 16px; } -} diff --git a/operations/pop-sync/env.prod b/operations/pop-sync/env.prod index 6494e85..4317c39 100644 --- a/operations/pop-sync/env.prod +++ b/operations/pop-sync/env.prod @@ -3,5 +3,5 @@ export TS_API_KEY=tskey-api-k7uLSqJS1121CNTRL-JF18cV5ajMBfE71sBQ5ZMB85zZJtKzVx export TS_AUTHKEY=tskey-auth-kuYFWy9jka11CNTRL-gskGJwSfcWfoF9XQNpmMWfNittrHzgcbc export AWS_ACCESS_KEY_ID=AKIA4QTBZQ4D4VPQEWGL export AWS_SECRET_ACCESS_KEY=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 -export SERVE_IP=185.218.204.47 export VAULT_BINARY=/opt/pop-sync/clavitor-arm64 +export ISHOSTING_API_KEY=RBF8mTdM4F8MfJdmvQFusNCGkCQEvSKtsdo2JFCeAm2gmGTodMogEfPLbnAaLCM3 diff --git a/operations/pop-sync/main.go b/operations/pop-sync/main.go index 069de30..4828c28 100644 --- a/operations/pop-sync/main.go +++ b/operations/pop-sync/main.go @@ -81,8 +81,9 @@ type Config struct { VaultSrc string // path to vault source (for local builds) VaultBinary string // path to pre-built vault binary (takes precedence) Nodes string // comma-separated node filter (empty = all) - AWSKeyID string - AWSSecretKey string + AWSKeyID string + AWSSecretKey string + ISHostingKey string } type NodeResult struct { @@ -121,6 +122,8 @@ func main() { exitWith(cmdExec(cfg, strings.Join(remaining, " "))) case "firewall": exitWith(cmdFirewall(cfg)) + case "update": + exitWith(cmdUpdate(cfg)) case "provision": if len(remaining) == 0 { fatal("usage: pop-sync provision [city2 ...] (e.g. pop-sync provision Tokyo Calgary)") @@ -220,6 +223,8 @@ func parseFlags() (Config, []string) { cfg.AWSKeyID = next() case "-aws-secret": cfg.AWSSecretKey = next() + case "-ishosting-key": + cfg.ISHostingKey = next() case "-dry-run", "--dry-run": cfg.DryRun = true case "-json", "--json": @@ -257,6 +262,9 @@ func parseFlags() (Config, []string) { if cfg.AWSSecretKey == "" { cfg.AWSSecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY") } + if cfg.ISHostingKey == "" { + cfg.ISHostingKey = os.Getenv("ISHOSTING_API_KEY") + } return cfg, remaining } @@ -503,6 +511,42 @@ func cmdExec(cfg Config, command string) []NodeResult { return results } +// --- Subcommand: update --- +// Runs system updates on all live nodes. + +func cmdUpdate(cfg Config) []NodeResult { + pops := filterNodes(cfg, loadLivePOPs(cfg)) + log(cfg, "Updating %d nodes...\n", len(pops)) + + updateCmd := `export DEBIAN_FRONTEND=noninteractive; ` + + `(apt-get update -qq && apt-get upgrade -y -qq && apt-get install -y -qq unattended-upgrades 2>/dev/null) || ` + + `(yum update -y -q 2>/dev/null) || ` + + `(dnf update -y -q 2>/dev/null) || true; ` + + `echo "update done"` + + results := parallelExec(pops, 4, func(p POP) NodeResult { + name := p.Subdomain() + r := NodeResult{Node: name, Action: "update"} + + log(cfg, " [%s] updating...", name) + out, err := tsSshExec(name, updateCmd) + if err != nil { + r.Error = fmt.Sprintf("%v", err) + log(cfg, " [%s] FAIL: %v", name, err) + return r + } + + r.OK = true + r.Message = "updated" + log(cfg, " [%s] done", name) + _ = out + return r + }) + + outputResults(cfg, results) + return results +} + // --- Subcommand: maintenance --- func cmdMaintenance(cfg Config, args []string) { @@ -734,10 +778,6 @@ func int32Ptr(i int32) *int32 { return &i } // Spins up t4g.nano EC2 instances for planned POPs. func cmdProvision(cfg Config, cities []string) []NodeResult { - if cfg.AWSKeyID == "" || cfg.AWSSecretKey == "" { - fatal("AWS credentials required: set AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or -aws-key/-aws-secret") - } - // Load all POPs from DB allPOPs, err := readPOPs(cfg.DBPath) if err != nil { @@ -767,7 +807,15 @@ func cmdProvision(cfg Config, cities []string) []NodeResult { var results []NodeResult for _, p := range targets { - r := provisionNode(cfg, p) + var r NodeResult + switch strings.ToLower(p.Provider) { + case "ishosting": + r = provisionISHosting(cfg, p) + case "aws": + r = provisionNode(cfg, p) + default: + r = NodeResult{Node: p.City, Action: "provision", Error: fmt.Sprintf("unknown provider: %s — use bootstrap for manual VPS", p.Provider)} + } results = append(results, r) } @@ -1097,7 +1145,13 @@ func cmdBootstrap(cfg Config, city, ip, password string) []NodeResult { } log(cfg, " [%s] connected (%s)", city, strings.TrimSpace(out)) - // --- Step 2: Install Tailscale --- + // --- Step 2: System update --- + log(cfg, " [%s] updating system...", city) + sshRaw("export DEBIAN_FRONTEND=noninteractive; apt-get update -qq && apt-get upgrade -y -qq && apt-get install -y -qq unattended-upgrades 2>/dev/null || (yum update -y -q 2>/dev/null) || true") + log(cfg, " [%s] system updated", city) + + // --- Step 3: Install Tailscale --- + // (renumbered from step 2) log(cfg, " [%s] installing Tailscale...", city) out, err = sshRaw("command -v tailscale >/dev/null 2>&1 && echo 'already installed' || (curl -fsSL https://tailscale.com/install.sh | sh)") if err != nil { @@ -1236,6 +1290,191 @@ systemctl is-active clavitor`, dns) return []NodeResult{r} } +// --- ishosting provisioner --- + +func provisionISHosting(cfg Config, pop POP) NodeResult { + r := NodeResult{Node: pop.City, Action: "provision"} + + if cfg.ISHostingKey == "" { + r.Error = "ISHOSTING_API_KEY required" + return r + } + + sub := pop.Subdomain() + if sub == "" { + sub = strings.ToLower(pop.Country) + "1" + } + dns := sub + "." + cfg.Zone + if pop.DNS != "" { + dns = pop.DNS + sub = pop.Subdomain() + } + + if cfg.DryRun { + r.OK = true + r.Message = fmt.Sprintf("would provision %s via ishosting as %s", pop.City, dns) + log(cfg, " [%s] DRY RUN: %s", pop.City, r.Message) + return r + } + + ishAPI := func(method, path string, body interface{}) (map[string]interface{}, error) { + var reqBody io.Reader + if body != nil { + data, _ := json.Marshal(body) + reqBody = bytes.NewReader(data) + } + req, _ := http.NewRequest(method, "https://api.ishosting.com"+path, reqBody) + req.Header.Set("X-Api-Token", cfg.ISHostingKey) + req.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + respBody, _ := io.ReadAll(resp.Body) + var result map[string]interface{} + json.Unmarshal(respBody, &result) + if resp.StatusCode >= 400 { + return result, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(respBody)) + } + return result, nil + } + + // Step 1: Find cheapest plan for this country + log(cfg, " [%s] finding plan for %s...", pop.City, pop.Country) + plans, err := ishAPI("GET", "/services/vps/plans", nil) + if err != nil { + r.Error = fmt.Sprintf("list plans: %v", err) + return r + } + + // Find the cheapest plan available in this country + var planCode string + var planPrice float64 = 999 + if items, ok := plans["items"].([]interface{}); ok { + for _, item := range items { + plan, _ := item.(map[string]interface{}) + locations, _ := plan["locations"].([]interface{}) + for _, loc := range locations { + locStr, _ := loc.(string) + if strings.EqualFold(locStr, pop.Country) { + price, _ := plan["price"].(float64) + if price > 0 && price < planPrice { + planPrice = price + code, _ := plan["code"].(string) + planCode = code + } + } + } + } + } + if planCode == "" { + r.Error = fmt.Sprintf("no plan found for country %s", pop.Country) + return r + } + log(cfg, " [%s] plan: %s ($%.2f/mo)", pop.City, planCode, planPrice) + + // Step 2: Place order + log(cfg, " [%s] placing order...", pop.City) + order := map[string]interface{}{ + "items": []map[string]interface{}{ + { + "action": "new", + "type": "vps", + "plan": planCode, + "location": pop.Country, + "additions": map[string]interface{}{ + "os": "linux/ubuntu22#64", + }, + }, + }, + } + orderResult, err := ishAPI("POST", "/billing/order", order) + if err != nil { + r.Error = fmt.Sprintf("place order: %v", err) + return r + } + + // Extract invoice ID + invoiceID := "" + if id, ok := orderResult["invoice_id"].(float64); ok { + invoiceID = fmt.Sprintf("%.0f", id) + } else if id, ok := orderResult["invoice_id"].(string); ok { + invoiceID = id + } + if invoiceID == "" { + r.Error = fmt.Sprintf("no invoice ID in response: %v", orderResult) + return r + } + log(cfg, " [%s] invoice: %s", pop.City, invoiceID) + + // Step 3: Pay invoice + log(cfg, " [%s] paying invoice...", pop.City) + _, err = ishAPI("POST", "/billing/invoice/"+invoiceID+"/pay", nil) + if err != nil { + r.Error = fmt.Sprintf("pay invoice: %v", err) + return r + } + + // Step 4: Wait for provisioning + get IP + log(cfg, " [%s] waiting for provisioning...", pop.City) + var publicIP string + for i := 0; i < 60; i++ { + time.Sleep(10 * time.Second) + services, err := ishAPI("GET", "/services/list?locations="+pop.Country, nil) + if err != nil { + continue + } + if items, ok := services["items"].([]interface{}); ok { + for _, item := range items { + svc, _ := item.(map[string]interface{}) + status, _ := svc["status"].(string) + if status == "active" { + if ip, ok := svc["ip"].(string); ok && ip != "" { + publicIP = ip + } else if ips, ok := svc["ips"].([]interface{}); ok && len(ips) > 0 { + if ip, ok := ips[0].(string); ok { + publicIP = ip + } + } + } + } + } + if publicIP != "" { + break + } + log(cfg, " [%s] still provisioning... (%ds)", pop.City, (i+1)*10) + } + if publicIP == "" { + r.Error = "timeout waiting for IP" + return r + } + log(cfg, " [%s] IP: %s", pop.City, publicIP) + + // Step 5: Update DB + localDB, _ := sql.Open("sqlite", cfg.DBPath) + localDB.Exec(`UPDATE pops SET ip=?, dns=?, status='live' WHERE pop_id=?`, publicIP, dns, pop.PopID) + localDB.Close() + pop.IP = publicIP + pop.DNS = dns + + // Step 6: Bootstrap (Tailscale, harden, deploy) — wait for SSH to be ready + log(cfg, " [%s] waiting for SSH...", pop.City) + time.Sleep(30 * time.Second) + + // Run bootstrap inline + bootstrapResult := cmdBootstrap(cfg, pop.City, publicIP, "") + if len(bootstrapResult) > 0 && !bootstrapResult[0].OK { + r.Error = fmt.Sprintf("bootstrap failed: %s", bootstrapResult[0].Error) + return r + } + + r.OK = true + r.Message = fmt.Sprintf("%s → %s (ishosting/%s) — live", publicIP, dns, pop.Country) + log(cfg, "\n [%s] DONE: %s\n", pop.City, r.Message) + return r +} + func ensureSecurityGroup(ctx context.Context, client *ec2.Client, region, city string, cfg Config) (string, error) { // Check if vault1984-pop exists in this region descOut, err := client.DescribeSecurityGroups(ctx, &ec2.DescribeSecurityGroupsInput{ diff --git a/operations/pop-sync/pop-sync b/operations/pop-sync/pop-sync index 571d5a2..ccf5176 100755 Binary files a/operations/pop-sync/pop-sync and b/operations/pop-sync/pop-sync differ diff --git a/operations/pop-sync/pop-sync-linux-amd64 b/operations/pop-sync/pop-sync-linux-amd64 index ce73502..fbb16e1 100755 Binary files a/operations/pop-sync/pop-sync-linux-amd64 and b/operations/pop-sync/pop-sync-linux-amd64 differ